Вопрос или проблема
Я пытаюсь написать скрипт, изменяющий для определённых сервисов тип запуска на “Automatic (DelayedStart)”. Когда я передаю сервисы в Set-CimInstance
, возникает ошибка, что “невозможно изменить только для чтения свойство ‘StartMode'”. Когда я передаю их в Invoke-CimMethod
, скрипт выполняется без ошибок (и возвращает 21), но ничего не меняется. Что я делаю не так и где можно получить список возвращаемых значений?
ForEach ($Server in $Servers) {
$Services = @("MSSQL", "MSSQLSERVER", "SQLAgent")
$Before = @()
ForEach ($Service in $Services) {
$Before += Get-CimInstance -ComputerName $Server -ClassName 'Win32_Service' -Property * | Where-Object -Property Name -like "*$Service*"
}
$Before | Format-Table -Property PSComputerName, Name, StartMode, DelayedAutoStart, State, StartName -AutoSize
ForEach ($Item in $Before.Name) {
Get-CimInstance -ClassName Win32_Service -ComputerName $Server -Filter "Name="$($Item)"" | Invoke-CimMethod -MethodName Change -Arguments @{StartMode = "AutomaticDelayedStart"}
# Get-CimInstance -ClassName Win32_Service -ComputerName $Server -Filter "Name="$($Item)"" | Set-CimInstance -Property @{StartMode = "AutomaticDelayedStart"}
### Error is: Set-CimInstance : Could not modify readonly property 'StartMode' of object 'Win32_Service: <Caption> <Name>
}
$After = @()
ForEach ($Service in $Services) {
$After += Get-CimInstance -ComputerName $Server -ClassName 'Win32_Service' -Property * | Where-Object -Property Name -like "*$Service*"
}
$After | Format-Table -Property PSComputerName, Name, StartMode, DelayedAutoStart, State, StartName -AutoSize
}
Я думаю, что главная проблема в том, что AutomaticDelayedStart
не является доступным режимом запуска для SQL Server:
Вы можете запросить у CIM список доступных режимов запуска с помощью следующего кода:
$c = Get-CimClass -ClassName Win32_Service
$p = $c.CimClassMethods | Where-Object Name -eq ChangeStartMode | Select-Object -ExpandProperty Parameters
$s = $p | Where-Object Name -eq StartMode
$v = $s.Qualifiers | Where-Object Name -eq ValueMap | Select-Object -ExpandProperty Value
Write-Host "Available StartModes: $($v -join ',')"
# Available StartModes: Boot,System,Automatic,Manual,Disabled
(Не знаю, почему Boot
или System
указаны там и не пробовал их использовать.)
Также можно более эффективно обновлять и заново получать объекты CIM, просто передавая их в соответствующий cmdlet. Следующий код работал у меня на локальной машине:
#Requires -RunAsAdministrator
$Servers = @(...)
$Services = @("MSSQL", "MSSQLSERVER", "SQLAgent")
$StartMode="Automatic"
ForEach ($Server in $Servers)
{
$Before = @()
ForEach ($Service in $Services)
{
$Before += Get-CimInstance -ComputerName $Server -ClassName 'Win32_Service' -Filter "Name="$Service""
}
$Before | Format-Table -Property PSComputerName, Name, StartMode, DelayedAutoStart, State, StartName -AutoSize
$After = @()
ForEach ($Item in $Before)
{
$Item | Invoke-CimMethod -MethodName Change -Arguments @{StartMode = "$StartMode"}
$After += $Item | Get-CimInstance
}
$After | Format-Table -Property PSComputerName, Name, StartMode, DelayedAutoStart, State, StartName -AutoSize
}
Ответ или решение
Когда дело доходит до автоматизации управления службами посредством PowerShell, особенно в случае настройки типа запуска службы как «Автоматически (с задержкой)», необходимо учитывать множество нюансов. Использование PowerShell для таких задач позволяет качественно и эффективно управлять инфраструктурой IT, однако требует детального подхода и понимания функционирования каждой команды и методов, которые задействованы в вашем скрипте.
Теория: Понимание StartMode и DelayedAutoStart
Переменные StartMode
и DelayedAutoStart
играют ключевую роль в управлении запуском служб. StartMode
определяет общий режим запуска службы, который может принимать значения, такие как Автоматический, Вручную или Отключено. DelayedAutoStart
дополняет Automatic
, позволяя системе откладывать запуск до завершения инициализации критически важных служб.
Важно понимать, что AutomaticDelayedStart
не является допустимым значением непосредственно для StartMode
. Вместо этого, комбинация StartMode
равным "Automatic" и свойством DelayedAutoStart
, установленным в True, обеспечит отложенный старт.
Пример: Проблемы с использованием Set-CimInstance и Invoke-CimMethod
В представленном примере были совершены некоторые ошибки, которые привели к недееспособности скрипта. Следует учитывать, что…
-
Invoke-CimMethod для изменения типа запуска использует метод
ChangeStartMode
и не поддерживает параметр DelayedAutoStart напрямую, так как это ограничениеInvoke-CimMethod
. -
Set-CimInstance выдает ошибку о том, что
StartMode
является свойством только для чтения в классеWin32_Service
. Это объясняется спецификой реализации этого класса в Windows.
Применение: Реализация правильной стратегии
Для корректного выполнения задачи на основе PowerShell, требуется комбинированное использование Set-Service
и Set-ItemProperty
через WMI и стандартные PowerShell-команды.
#Комплект переменных
$Servers = @(...) # ваш список серверов
$Services = @("MSSQL", "MSSQLSERVER", "SQLAgent")
ForEach ($Server in $Servers) {
# Подключение к удаленному серверу
Invoke-Command -ComputerName $Server -ScriptBlock {
Param($Services)
ForEach ($Service in $Services) {
# Профессиональный подход: Изменение StartMode на Automatic
Set-Service -Name $Service -StartupType Automatic
# Используем WMI для установки DelayedAutoStart в True
$serviceObj = Get-WmiObject -Class Win32_Service -Filter "Name='$Service'"
$serviceObj.ChangeStartMode("Automatic")
$null = Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$($Service)" -Name DelayedAutostart -Value 1
# Вывод текущих статусов служб
Get-Service -Name $Service | Select-Object DisplayName, Status, StartType | Format-Table -AutoSize
}
} -ArgumentList ($Services)
}
Заключение и дополнительные соображения
Предложенный подход сочетает в себе использование как PowerShell, так и WMI-команд, обеспечивая должный контроль за службами с возможностью откладывания их запуска. Важно всегда тестировать такие скрипты в контролируемой среде, чтобы избежать неожиданных последствий на производственных серверах.
При автоматизации подобных процессов необходимо не только внимание к синтаксису команд, но и понимание принципов работы операционной системы, с учетом того, что каждое изменение конфигурации может влиять на стабильность сервисов и программных компонентов. Создавая скрипты, управляющие такими процессами, всегда заботьтесь о тестировании и документировании любой инфраструктурной модификации.