Dkms's Blog on WordPress

PS и WSS 3

Posted in PowerShell, Sharepoint by DkmS on 28.02.2009

Продолжаем наши танцы эксперименты. В этот раз решаем простую задачку автоматического утверждения содержимого элемента списка. Решаем в технике использования обработчиков событий, т.к. в нём скрипты работают в контексте текущего пользователя и нет необходимости проверят его разрешения. Скрипт получается совсем простой:

   1:  function ApproveItemContent {
2: if (-not $list.EnableModeration ){ return; }
3: if ($item.ModerationInformation.Status –eq
Microsoft.SharePoint.SPModerationStatusType]::Approved `
4: -or `
5: $item.ModerationInformation.Status –eq
Microsoft.SharePoint.SPModerationStatusType]::Denied)
6: { return; }
7: $this.DisableEventFiring()
8: try{
9: $item.ModerationInformation.Status = `
10: [Microsoft.SharePoint.SPModerationStatusType]::Approved;
11: $item.ModerationInformation.Comment = 'Approved with PS-script by user '
12: + $user.Name + ' at ' + [System.DateTime]::Now.ToString();
13: $item.SystemUpdate();
14: }catch{
15: # не очень и хотелось...
16: }
17: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Эту функцию записываем в конец заготовки обработчика и ставим её вызов в обработчики добавления и обновления:


function ItemAdded{ ApproveItemContent; } function ItemUpdated{ ApproveItemContent; }

Не обошлось, как водится, без сюрпризовsmile_nerd: на списке вики-страниц ( узел создавался с шаблоном “вики”) скрипт работает наполовину – комментарий (строка 11) записывается, а статус (строка 9) – нет. При расследовании выяснилось, что исправляет дело замена SystemUpdate() на Update() в строке 13.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Technorati Tags: ,

PS и WSS 2

Posted in PowerShell, Sharepoint by DkmS on 27.02.2009

Во второй серии балета экспериментов пытаемся сделать при помощи PS-технологии нечто содержательное. Например, достаточно часто требуется для элементов списка (документов библиотеки) оставить доступ только создателю и некоторым группам пользователей, отобрав его у всех остальных. Достаточно легко эта операция проделывается при помощи рабочего процесса с использованием activities из пакета Useful Sharepoint Designer Custom Workflow Activities. Алгоритм достаточно простой:

  1. Убрать наследование разрешений
  2. Установить разрешения для групп
  3. Установить разрешения для создателя.

Для использования в обработчике событий PowerEventReceivers имеет смысл написать функцию, выполняющую нужные действия, и вызывать её из обработчиков ItemAdded и ItemUpdated. Функция получается такая:

function ResetPermissions{
$groupsNames = "Администрация", "ИТ Отдел";
$permissionLevelName = "Полный доступ";
$permissionLevel = $null;
$mustSave=$false;
if( -not $item.HasUniqueRoleAssignments){
    try{ $item.BreakRoleInheritance($false); }
    catch{
        # у пользователя нет нужных разрешений
        return;
    }
}
if($item.HasUniqueRoleAssignments){
    try{
        $permissionLevel = $web.RoleDefinitions[$permissionLevelName];
    }catch{
        # у пользователя нет разрешений или неверно задан уровень
    }
    if($permissionLevel -ne $null){
        try{
            foreach ($groupName in $groupsNames) {
                $group = $null;
                try{$group = $web.Groups[$groupName];}catch{} #on web
                if($group -eq $null) {try{$group = $web.Site.Rootweb.Groups[$groupName];}catch{}} #on site
                if($group -eq $null) {continue;} #wrong group
                $role = New-Object -TypeName Microsoft.SharePoint.SPRoleAssignment -ArgumentList $group;
                $role.RoleDefinitionBindings.Add($permissionLevel);
                $item.RoleAssignments.Add($role);
                $mustSave=$true;
            }
        }catch{
            if(-not $mustSave){
                return;
            }
        }
        #Creator
        try{
            $user = (($item.Fields[[Microsoft.SharePoint.SPBuiltInFieldId]::Author] `
            -as [Microsoft.SharePoint.SPFieldUser]).GetFieldValue($item[[Microsoft.SharePoint.SPBuiltInFieldId]::Author].ToString()) `
            -as [Microsoft.SharePoint.SPFieldUserValue]).User;
            $userRole = New-Object -TypeName Microsoft.SharePoint.SPRoleAssignment -ArgumentList $user; #SPRoleAssignment
            $userRole.RoleDefinitionBindings.Add($permissionLevel);
            $item.RoleAssignments.Add($userRole);
            $mustSave=$true;
        }catch{
            if(-not $mustSave){
                return;
            }
        }
    }
    if($mustSave){ # сохранить изменения
        $item.SystemUpdate();
    }
}
## End of ResetPermissions ##
}

Такая функция исполняется ожидаемым образом только когда изменения списка проводит пользователь, имеющий права на изменение разрешений. У пользователя, не имеющего таких прав, дело заканчивается неудачей и разрешения на элемент списка наследуются от списка. Внутри скрипта дело поправить не удаётся (нужно выполнить код с системными привилегиями), поэтому следует искать другие выходы.

Выходов, как обычно, находится два: заставить изменить элемент пользователя с нужными правами или применить другие средства. Можно, например, в списке настроить обязательное утверждение элементов, и в момент утверждения все необходимые действия будут выполнены.

Из “других” средств можно применить SharePoint Designer PowerActivity того же автора. В рабочем процессе, основанном на этой “активности”, можно применить тот же самый скрипт, что и в обработчике событий. С учётом того, что рабочие процессы выполняются в контексте системной учётной записи, изменения проходят у любого пользователя, имеющего разрешения на добавление и/или редактирование элементов списков. Платой за это служит необходимость иметь SPD.

Тексты скриптов для обработчика (RecieverScript.ps1) и для PowerActivity (WFScript.ps1) можно взять здесь.

Technorati Tags: ,

PS и WSS

Posted in PowerShell, Sharepoint by DkmS on 24.02.2009

В то время как по всей России страдают многие энтузиасты ратуют за использование PowerShell в деле борьбы работы с Шарепойнтом, как-то у меня самого дальше советов пользователям форума пока не продвинулось. smile_embaressed Надо восполнить пробел…

Первая серия экспериментов – с обработчиком событий iLoveSharePoint.PowerEventReceivers, представленным Christian’ом Glessner’ом (http://www.iLoveSharePoint.com). Задача – попробовать, легко ли писать скрипты для этого обработчика и как эти скрипты должны выглядеть. Содержательно – скрипты должны добавлять свои сообщения в предназначенное для этого поле.

Результат: скрипты писать легко и просто, совсем как в Студии на C#, но можно и не обращать внимания на регистр символов (спасибо MS за любовь к BASIC’у). Вид же скриптов сильно зависит от типа обработчика (вызов перед началом события/после события). Гугль подсказывает, что народ с этим постоянно сталкивается и пытается бороться. Поэтому просто примем это за реальность и правила будем использовать такие:

  • в методах, вызываемых перед началом события (ItemAdding, ItemUpdating и т.п.) работаем с After-свойствами:
    function ItemAdding{
    $message="Adding;"; $fieldName="msg"; 
    $internalFieldName=$list.Fields[$fieldName].InternalName; $properties.AfterProperties[$internalFieldName]+=$message; }

    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, “Courier New”, courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }

  • В методах, вызываемых после события (ItemAdded, ItemUpdated и т.п.) работаем с полями элемента списка: 
    function ItemAdded{
    $message="Added;"; $fieldName="msg"; 
    $internalFieldName=$list.Fields[$fieldName].InternalName;
    $item[$internalFieldName]+=$message; 
    $item.SystemUpdate();
    }
Technorati Tags: ,
Follow

Get every new post delivered to your Inbox.

Join 76 other followers