CM: Функция добавления кода выхода к типу развертывания

Итак, появилась очередная задача — приложение при замене возвращает код, который клиент Configuration Manager не ожидает. В частности, браузер Яндекс возвращает код 3 при обновлении. Чтобы автоматизировать процесс выкладки приложения был написан большой скрипт, который проверяет наличие нового дистрибутива и публикует его в Configuration Manager. При его написании использовались стандартные командлеты. К сожалению, среди них не оказалось командлетов, которые могли бы добавить необходимый код выхода к требуемому типу развертывания. Ниже приведен код функции, которая решает данную проблему:

function Add-CMDeploymentTypeReturnCode
{
    param(
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true)]
        [Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine.WqlResultObject[]]$DeploymentType,
        [Parameter(
            Mandatory = $true,
            Position = 1)]
        [int]$Value,
        [Parameter(
            Mandatory = $true,
            Position = 2)]
        [Microsoft.ConfigurationManagement.ApplicationManagement.ExitCodeClass]$CodeType,
        [Parameter(
            Mandatory = $false,
            Position = 3)]
        [string]$Name = $null,
        [Parameter(
            Mandatory = $false,
            Position = 4)]
        [string]$Description = $null
    )
    begin
    {
        $ExitCode = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.ExitCode
        $ExitCode.Code = $Value
        $ExitCode.Class = $CodeType
        if (![string]::IsNullOrEmpty($Name))
        {
            $ExitCode.Name = $Name
        }
        if (![string]::IsNullOrEmpty($Description))
        {
            $ExitCode.Description = $Description
        }
    }
    process
    {
        foreach ($Type in $DeploymentType)
        {
            $Application = Get-CMApplication -ModelName $Type.AppModelName
            $UniqueID = $Type.CI_UniqueID
            $ObjectId = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.ObjectId($UniqueID.Split("/"))
            $SDMPackage = [Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer]::DeserializeFromString($Application.SDMPackageXML)
            $SDMPackage.DeploymentTypes[$ObjectId].Installer.ExitCodes.Add($ExitCode)
            $Application.SDMPackageXML = [Microsoft.ConfigurationManagement.ApplicationManagement.Serialization.SccmSerializer]::Serialize($SDMPackage, $false)
            $Application.Put()
        }
    }
}

Пример использования функции:

Get-CMApplication -Name "Yandex Browser" | Get-CMDeploymentType | Add-CMDeploymentTypeReturnCode -Value 3 -CodeType Success -Name "Update" -Description "Update"

CM: Поддерживать неподдерживаемое

Итак, у компании появилась потребность в обслуживании рабочих станций на базе UNIX/Linux, при этом в организации уже есть развернутый SCCM, который до недавнего времени поддерживал работу с этим классом операционных систем. Поддержка остановилась на версии Current Branch 1810 и в версии 1902 такой поддержки больше нет. Тем не менее, техническая возможность есть продолжить использовать кроссплатформенные клиенты и в списках операционных систем они никуда не делись. Остаются две проблемы:

  1. В списках нет последних вышедших операционных систем
  2. Установка клиента завершается с ошибкой на неподдерживаемую версию OpenSSL

Для того, чтобы решить первую проблему необходимо  выполнить запрос в базе данных Configuration Manager, который добавит в список отсутствующие операционные системы (в моем примере Debian 9, 10 и Ubuntu 18.04):

INSERT INTO SupportedPlatforms
	(Id, OSPlatform, OSName, OSMinVersion, OSMaxVersion, DisplayText, StringId, Condition, ClientSupported, Metric, BitMask, HybridSupported)
	VALUES
	(4148, 'x86', 'Debian', '9.00.0000.0', '9.99.9999.9999', 'x86 Debian 9', 4148, '<Operator OperatorType="AND"><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_OperatingSystem WHERE Version like ''9%'' AND OSType=36 AND Caption like ''%Debian GNU/Linux 9%'']]></Expression><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_Processor WHERE Architecture=0]]></Expression></Operator>', 1, 200, 0, 0),
	(4149, 'x64', 'Debian', '9.00.0000.0', '9.99.9999.9999', 'x64 Debian 9', 4149, '<Operator OperatorType="AND"><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_OperatingSystem WHERE Version like ''9%'' AND OSType=36 AND Caption like ''%Debian GNU/Linux 9%'']]></Expression><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_Processor WHERE Architecture=9]]></Expression></Operator>', 1, 200, 0, 0),
	(4150, 'x86', 'Ubuntu', '18.04.0000.0', '18.04.9999.9999', 'x86 Ubuntu 18.04', 4150, '<Operator OperatorType="AND"><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_OperatingSystem WHERE Version like ''18.%'' AND OSType=36 AND Caption like ''%Ubuntu 18%'']]></Expression><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_Processor WHERE Architecture=0]]></Expression></Operator>', 1, 200, 0, 0),
	(4151, 'x64', 'Ubuntu', '18.04.0000.0', '18.04.9999.9999', 'x64 Ubuntu 18.04', 4151, '<Operator OperatorType="AND"><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_OperatingSystem WHERE Version like ''18.%'' AND OSType=36 AND Caption like ''%Ubuntu 18%'']]></Expression><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_Processor WHERE Architecture=9]]></Expression></Operator>', 1, 200, 0, 0),
	(4152, 'x86', 'Debian', '10.00.0000.0', '10.99.9999.9999', 'x86 Debian 10', 4152, '<Operator OperatorType="AND"><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_OperatingSystem WHERE Version like ''10%'' AND OSType=36 AND Caption like ''%Debian GNU/Linux 10%'']]></Expression><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_Processor WHERE Architecture=0]]></Expression></Operator>', 1, 200, 0, 0),
	(4153, 'x64', 'Debian', '10.00.0000.0', '10.99.9999.9999', 'x64 Debian 10', 4153, '<Operator OperatorType="AND"><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_OperatingSystem WHERE Version like ''10%'' AND OSType=36 AND Caption like ''%Debian GNU/Linux 10%'']]></Expression><Expression ExpressionType="continuous" ExpressionLanguage="WQL"><![CDATA[SELECT * FROM Win32_Processor WHERE Architecture=9]]></Expression></Operator>', 1, 200, 0, 0)

Для решения второй проблемы необходимо перейти по ссылке Open Management Infrastructure, скачать и установить последнюю версию OMI на компьютер, на который мы хотим установить агент. По ссылке Microsoft System Center Configuration Manager — Clients for Additional Operating Systems необходимо скачать и распаковать клиенты для необходимых операционных систем. В файле install необходимо заменить строку, содержащую запись

OPENSSL_SYSTEM_VERSION_100=

на

OPENSSL_SYSTEM_VERSION_100=`echo $OPENSSL_SYSTEM_VERSION_FULL | grep -Eq '^1.(0|1).'; echo $?`​

, после чего клиент уже можно установить по стандартному сценарию, описанному в документации.

Важно! При использовании данных манипуляций у вас возобновится возможность фильтровать развертывание пакетов как на уровне коллекций, так и на уровне операционной системы клиента. Вы должны отдавать себе отчет в том, что данные действия вы выполняете на свой страх и риск, все описанные действия на момент написания статьи являются неподдерживаемыми.

CM: Cmdlet для создания иконки приложения

Наверняка, многие из тех, кто использует командлеты Configuration Manager, сталкивались с проблемой создания приложения с иконкой размером больше 250×250. При попытке добавить иконку большего размера с помощью командлета New-CMApplication или Set-CMApplication выдается сообщение:

WARNING: The maximum size of an icon is 250px X 250px.

Об этом также есть отзыв на странице UserVoice — New-CMApplication rejects icons larger than 250×250

Ниже приведен командлет, который я использую для добавления иконок большего размера

function New-CMApplicationIcon {
    [OutputType([Microsoft.ConfigurationManagement.ApplicationManagement.Icon])]
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
        [System.IO.FileInfo]$FileName
    )
    process {
        [System.Drawing.Image]$Bitmap = $null
        [Microsoft.ConfigurationManagement.ApplicationManagement.Icon]$Icon = $null
        try {
            if ($FileName.Exists) {
                $Bitmap = [System.Drawing.Image]::FromFile($FileName.FullName)
                if ($Bitmap.Height -gt 512 -or $Bitmap.Width -gt 512) {
                    throw "Image size is out of range"
                }
                $Icon = New-Object Microsoft.ConfigurationManagement.ApplicationManagement.Icon($Bitmap)
                return $Icon
            }
        }
        finally {
            if ($Bitmap -ne $null) {
                $Bitmap.Dispose()
                $Bitmap = $null
            }
        }
    }
}

Далее мы можем использовать этот командлет совместно с остальными командлетами Configuration Manager, например:

$ApplicationIcon = New-CMApplicationIcon `
    -File ".\Icon\512px-Yandex_Browser_logo.png"
$LanguageId = [System.Globalization.CultureInfo]::GetCultureInfo("ru-ru").LCID
$DisplayInfo = New-CMApplicationDisplayInfo `
    -LanguageId $LanguageId `
    -Title "Яндекс Браузер" `
    -Description "Быстрый и безопасный браузер с голосовым помощником Алисой."
$DisplayInfo.Icon = $ApplicationIcon
$Application = New-CMApplication `
    -Name "Yandex Browser" `
    -Publisher "Yandex" `
    -SoftwareVersion "Latest" `
    -ReleaseDate [DateTime]::Today `
    -AppCatalog $DisplayInfo `
    -DefaultLanguageId $LanguageId

 

System Center 2019

Во всех доступных подписках Microsoft (VLSC, MSDN, Evaluation) стали доступны продукты линейки System Center 2019! Пробные версии продуктов можно скачать по ссылке Evaluate System Center 2019.

OM: OMS-Agent-for-Linux

https://github.com/Microsoft/OMS-Agent-for-Linux

OM: Скрипт для сброса состояния монитора

Скрипт для сброса монитора в здоровое состояние (аналогично Reset Health в Health Explorer) по критерию:

$Server = "ServerName"
$Credentials = Get-Credential
New-SCOMManagementGroupConnection -ComputerName $Server -Credential $Credentials
$ResetAlerts = Get-SCOMAlert -Criteria "IsMonitorAlert = 1 AND Name = 'Failed to Connect to Computer' AND ResolutionState < 255"
foreach ($Alert in $ResetAlerts)
{
	$MonitoringRule = Get-SCOMMonitor -Id $Alert.MonitoringRuleId
	$MonitoringObject = Get-SCOMClassInstance -Id $Alert.MonitoringObjectId
	$MonitoringObject.ResetMonitoringState($MonitoringRule)
}

OM: Docker-Provider

https://github.com/Microsoft/Docker-Provider/releases

OM: SCXCore-kits

https://github.com/Microsoft/SCXcore-kits

PSScript: Определение архитектуры

Нашел скрипт в просторах интернета, который определяет архитектуру (битность) библиотеки и немного доработал его.

function Get-FilePlatform
{
    param
    (
        [ValidateScript({$_.Exists})]
        [System.IO.FileInfo]$FileName
    )
    [int]$PE_POINTER_OFFSET = 60;            
    [int]$MACHINE_OFFSET = 4;
    [byte[]]$Data = New-Object byte[] 4096;
    [IO.Stream]$Stream = New-Object IO.FileStream($FileName, [IO.FileMode]::Open, [IO.FileAccess]::Read)
    $Stream.Read($Data, 0, $Data.Length) | Out-Null
    [int]$PE_HEADER_ADDR = [BitConverter]::ToInt32($Data, $PE_POINTER_OFFSET);
    [int]$MachineUint = [BitConverter]::ToUInt16($Data, $PE_HEADER_ADDR + $MACHINE_OFFSET);
    switch($MachineUint)
    {
        0x0000 {"Native"}
        0x014c {"x86"}
        0x0200 {"Itanium"}
        0x8664 {"x64"}
    }
    $Stream.Close()
}

OM: Как закрыть активные алерты для здоровых мониторов

В Operations Manager иногда бывают ситуации, когда монитор переходит в здоровое состояние, но алерт продолжает висеть во вкладке активных алертов. В большинстве случаев это следствие ошибок оператора. Очень часто бывает, что система уже закрыла алерт, но оператор в это время заполняет поля алерта и возвращает ему прежнее состояние. Такой алерт самостоятельно уже не закроется. Чтобы не искать такие алерты вручную, можно воспользоваться следующим скриптом:

$Server = "ServerName"
$Credentials = Get-Credential
New-SCOMManagementGroupConnection -ComputerName $Server -Credential $Credentials
$ActiveAlerts = Get-SCOMAlert -Criteria "IsMonitorAlert = 1 AND ResolutionState < 255"
foreach ($Alert in $ActiveAlerts)
{
	$MonitoringRule = Get-SCOMMonitor -Id $Alert.MonitoringRuleId
	$MonitoringObject = Get-SCOMMonitoringObject -Id $Alert.MonitoringObjectId
	$MonitorList = New-Object System.Collections.Generic.List[Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitor]
	$MonitorList.Add($MonitoringRule)
	$MonitoringState = $MonitoringObject.GetMonitoringStates($MonitorList)
	if ($MonitoringState.HealthState -eq [Microsoft.EnterpriseManagement.Configuration.HealthState]::Success)
	{
		$Alert
		$Alert | Resolve-SCOMAlert -Comment "The alert was manually closed because the monitor is in healthy state."
	}
}

Необходимо задать переменную $Server, указав имя сервера управления Operations Manager, после чего запустить скрипт.