А АFriday, 6 August 2021

Выполнение скриптов в SCCM на лету.

Всем привет.

MS SCCM имеет полезную фишку в библиотеке - Scripts. SCCM позволяет выполнять Powershell script-ы на целевых коллекциях или хостах без выгрузки кода скрипта в виде файла и  последующего запуска. Т.е. в таком случае можно оперативно выполнить запрос или задать параметр в ОС хоста, даже если выполнение Powershell-скриптов запрещено политикой компании. Простой пример: удалим софт по имени, который был установлен некорректно. Т.е. штатно его удалить невозможно.

Пишем код: 

Param (

[string]$Prgname

)

$PSVersionTable.PSVersion

$app = Get-WmiObject -Class Win32_Product -Filter "Name like '%$Prgname%'"

$app.Uninstall()

утверждаем (approve) его и пытаемся выполнить в нужной коллекции.


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

У такого подхода есть пара недостатков. Первый это то что несмотря на наличие приложения в системе WMI-запрос может его не найти. Это главный недостаток в работе с классом Win32_Product.

Поэтому есть смысл проверить вывод явно: 

Get-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name like '%7-Zip%'"

Или выбрать весь список установленного софта: 

Get-WmiObject -Query "SELECT * FROM Win32_Product" | Select Name 

Можете софт проверить и другим запросом:

Get-WmiObject -Query "SELECT * FROM Win32Reg_AddRemovePrograms WHERE DisplayName like '%7-Zip%'" 

Но, к сожалению, класс Win32Reg_AddRemovePrograms не имеет метода Uninstall().

Второй недостаток - это возникающий запрос пользователю на разрешение выполнения самого удаления. Сообщение может быть таким "PowerShell is in NonInteractive mode. Read and Prompt functionality is not available." В коде можно пробовать бороться с этим указанием флага -Recurse. 

Тогда команда выглядит так:

$app.Uninstall() -Recurse

Этого не всегда бывает достаточно. Интерактивный режим означает, что необходимо взаимодействовать со скриптами и давать какие-то ответы на вопросы формата yes/no. Это можно отключить так:

$app.Uninstall() -Recurse -Force

Такой вариант позволять избегать вопросов от powershell о подтверждении того или иного действия. Но даже этого иногда бывает недостаточно. В таком случае необходимо проставить флаг -Confirm:$false. Можно рискнуть и использовать все варианты сразу, чтобы точно обойти эту неприятную ошибку:

$app.Uninstall() -Recurse -Confirm:$false -Force

Успехов.

1 comment:

Nyukers said...

Клиент возвращает выходные данные скрипта с использованием форматирования JSON путем передачи его результатов в командлет ConvertTo-JSON. Формат JSON согласованно возвращает доступные для чтения выходные данные скрипта. Для скриптов, которые не возвращают объекты в качестве выходных данных, командлет ConvertTo-Json преобразует выходные данные в простую строку, возвращаемую клиентом вместо JSON.

Скрипты с неизвестным результатом или скрипты, при выполнении которых клиент находился в автономном режиме, не отображаются в диаграммах или наборе данных.
Следует избегать больших выходных данных скрипта, так как они усекаются до 4 КБ.

Для правильного отображения сценариев в формате JSON необходимо преобразовать объект enum в строковое значение. Преобразование объекта enum в строковое значение:
Get-Host | ConvertTo-Json
(Get-Host).ToString() | ConvertTo-Json

Post a Comment

А что вы думаете по этому поводу?

Версия на печать

Популярное