Показаны сообщения с ярлыком PowerShell. Показать все сообщения
Показаны сообщения с ярлыком PowerShell. Показать все сообщения

суббота, декабря 29, 2012

Hyper-V features in VirtualBox

Одна из понравившихся вещей в Hyper-V, которые хотелось бы иметь в VirtualBox после удаления Hyper-V - автоматическое сохранение состояния виртуальных машин при перезагрузке или выключении.

Отсутствие такой feature при непрекращающейся любви разработчиков Windows к перезагрузкам при установке обновлений (и участившихся выпусках самих обновлений) очень угнетает. Однажды даже забыл сохранить виртуалку с контроллером домена и после загрузки пришлось её восстанавливать из "снимка"…

Небольшие раскопки показывают, что VB предоставляет необходимые средства для управления виртуальными машинами, остаётся лишь соединить их между собой для получения недостающих возможностей.

Вот PS-скрипт, который сохраняет все работающие виртуальные машины и выполняет перезагрузку или выключение компьютера:

clip_image001

"Побочный" результат работы скрипта - список работающих виртуалок в текстовом файле. Этот список можно использовать для реализации второй недостающей feature - восстановления ранее работавших виртуальных машин.

Вот соответствующий скрипт:

clip_image002

Остаётся сделать на рабочем столе ярлыки для запуска этих скриптов и использовать при необходимости перезагрузиться и при запуске машин после перезагрузки.

пятница, декабря 28, 2012

Бойся Try/Catch…

Вот, только что наткнулся: конструкция try/catch в PS v.2 (которая с Шарепойнтом 2010 только и работает) срабатывает в зависимости от типа ошибки - некоторые вовсе не перехватывает.

Пример: конструкция try{2/0}catch{"низя!"} вываливает сообщение в консоль:

clip_image001

PS v.3 исполняет как надо:

clip_image002

Выясняется, правда, что если делить не на нуль, а на переменную, содержащую нуль, то этот примерчик работает и во второй версии:

clip_image003

С другой стороны, наткнулся-то я на такое смешное поведение Catch в реальном скрипте при попытке в блоке Try записать данные в системный лог:

Write-EventLog -LogName $eventLogName -Source $eventLogSourceName ...

Если переменная $eventLogSourceName пустая, то в Catch ловится ошибка с сообщением "Cannot validate argument on parameter 'Source'. The argument is null or empty."

А если там неверное значение, то исключение не ловится и сообщение пишется в консоль:

clip_image004

Как с этим бороться? Не перечислять же все известные в природе исключения? Тем более, что некоторые всё равно не перехватываются…

Нашёлся способ в виде конструкции Trap - нечто наподобие On Error в бейсике.

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

Вот примерчик:

$err="Error: "

trap {  $err += $_
$err
Out-File -FilePath "errors.log" -Encoding "utf8" -Append -InputObject $_.Exception.Message
continue }

$dvdr = 0
1/$dvdr
NonsenseString 
2+3
$err #здесь та же строка "Error: " :(

Здесь выполняются все действия, а сообщения об ошибках выводятся в файл:


Попытка деления на нуль.
Имя "NonsenseString" не распознано как имя командлета, функции, файла скрипта или выполняемой программы.


Не фонтан, конечно, но, всё же, лучше, чем просто пропадающее сообщение (пускай даже код после "кривых" Catch иногда и выполняется нормально)…

пятница, декабря 21, 2012

Троянский конь…

С декабрьским пакетом обновлений установился Windows Management Framework 3.0 for Windows Server. Спасибо, конечно, но можно было бы и предупредить, что при попытке воспользоваться “Командной консолью Sharepoint 2010” получим сообщение “The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.”

Конечно, новый PS работает под .NET 4.0, а Sharepoint – под 3.5…

Хорошо хоть, что решается проблемка простым удалением этого “обновления”. Но опять перезагрузка… А на сервере люди…

суббота, февраля 28, 2009

PS и WSS 3

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

   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: }

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


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

Technorati Tags: ,

пятница, февраля 27, 2009

PS и WSS 2

Во второй серии балета экспериментов пытаемся сделать при помощи 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: ,

вторник, февраля 24, 2009

PS и WSS

В то время как по всей России страдают многие энтузиасты ратуют за использование 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;
    }

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

Technorati Tags: ,