Сценарий Powershell для изменения учетной записи службы

У кого-нибудь есть сценарий Powershell для изменения учетных данных, используемых службой Windows?


person Jesse Weigert    schedule 24.11.2008    source источник
comment
Можете ли вы удалить текст бонусного вопроса? Я заметил, что вы разместили это отдельно. Давайте не будем путать людей и заставлять ответы идти не по адресу.   -  person halr9000    schedule 24.11.2008
comment
Использование sc.exe также является вариантом.   -  person jpmc26    schedule 14.04.2017


Ответы (11)


Немного проще - используйте WMI.

$service = gwmi win32_service -computer [computername] -filter "name='whatever'"
$service.change($null,$null,$null,$null,$null,$null,$null,"P@ssw0rd")

Изменить имя службы соответствующим образом в фильтре; правильно задайте имя удаленного компьютера.

person Don Jones    schedule 24.11.2008
comment
Просто примечание к этому ответу. Если вы хотите обновить учетную запись пользователя, вам необходимо обновить значение, предшествующее паролю. то есть $service.change($null,$null,$null,$null,$null,$null,.\MyAccount,P@ssw0rd). Кажется, вам всегда нужно ставить префикс имени учетной записи с именем домена или .\, иначе это не сработает. Дополнительные сведения о других параметрах см. здесь: msdn.microsoft.com/en-us/library/windows/desktop/ - person Rohland; 19.06.2012
comment
Кроме того, взгляните на мой ответ ниже, прежде чем использовать это. Изменения учетной записи службы требуют сброса службы, чтобы они вступили в силу, и образец кода включен. - person Chris N; 12.09.2012
comment
Обратите внимание: если вы указываете учетную запись, отличную от локальной системы, в соответствии с приведенным выше комментарием @Rohland, вы также должны указать $false для параметра 6 (DesktopInteract). Только учетной записи локальной системы могут быть предоставлены разрешения на взаимодействие с рабочим столом. - person alastairs; 17.01.2013
comment
в моем пароле есть "$", как мне его избежать? - person Chris Hayes; 07.11.2013
comment
Вместо этого вы должны иметь возможность использовать жесткую (одинарную) кавычку. - person Chris N; 22.01.2014
comment
У меня было много проблем с этим подходом... много разных неудач. В итоге я обнаружил, что вызов sc намного надежнее: & sc.exe config "$servicename" obj= "[$domain\$username]" password= "[$password]" -- ссылка: stackoverflow.com/questions/308298 - person Jude Allred; 03.02.2014
comment
Вместо фильтрации по имени вы можете фильтровать по DisplayName, что может облегчить проблемы, когда в имени есть «$». - person Nick DeMayo; 07.03.2014
comment
Для всех, кто интересуется сигнатурой этого метода change() класса Win32_Service, посмотрите здесь: msdn.microsoft.com/en-us/library/aa384901(v=vs.85).aspx - person J T R; 14.05.2014
comment
Если мне нужен доступ к ComputerName с использованием имени пользователя и пароля, отличных от учетных данных службы Windows? - person Kiquenet; 17.10.2014
comment
не работает. ни sc в центре обработки данных Windows 2019. Если его вручную изменить на пользователя, а затем запустить, он работает (но это не то, что я хотел) - person Blue Clouds; 19.06.2020

Я написал функцию для PowerShell, которая меняет имя пользователя, пароль и перезапускает службу на удаленном компьютере (можно использовать localhost, если вы хотите изменить локальный сервер). Я использовал это для ежемесячного сброса пароля учетной записи службы на сотнях серверов.

Вы можете найти копию оригинала по адресу http://www.send4help.net/change-remote-windows-service-credentials-password-powershel-495

Он также ждет, пока служба полностью не остановится, чтобы попытаться запустить ее снова, в отличие от одного из других ответов.

Function Set-ServiceAcctCreds([string]$strCompName,[string]$strServiceName,[string]$newAcct,[string]$newPass){
  $filter = 'Name=' + "'" + $strServiceName + "'" + ''
  $service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
  $service.Change($null,$null,$null,$null,$null,$null,$newAcct,$newPass)
  $service.StopService()
  while ($service.Started){
    sleep 2
    $service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
  }
  $service.StartService()
}
person Chris N    schedule 06.12.2010
comment
Отлично +1. Вы должны отредактировать и включить строку использования. Использование: Set-ServiceAcctCreds -strCompName Computer1 -strServiceName Service -newAcct DOM\ServiceUser -newPass 'newSecureWord' - person DGaleano; 10.02.2016

Я создал текстовый файл «changeserviceaccount.ps1», содержащий следующий скрипт:

$account="domain\user"
$password="passsword"
$service="name='servicename'"

$svc=gwmi win32_service -filter $service
$svc.StopService()
$svc.change($null,$null,$null,$null,$null,$null,$account,$password,$null,$null,$null)
$svc.StartService()

Я использовал это как часть командной строки после сборки во время разработки службы Windows:

Visual Studio: свойства проекта\события сборки

Командная строка события предварительной сборки:

"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installutil.exe" myservice.exe /u

Командная строка события после сборки:

"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installutil.exe" myservice.exe
powershell -command - < c:\psscripts\changeserviceaccount.ps1
person AndyM    schedule 01.07.2010

Версия PowerShell 6 Set-Service теперь имеет параметр -Credential.

Вот пример:

$creds = Get-Credential
Set-Service -DisplayName "Remote Registry" -Credential $creds

На данный момент его можно загрузить только через GitHub.

Наслаждаться!

person Lockszmith    schedule 03.04.2018
comment
Я думаю, что -Credentials на самом деле должно быть -Credential - person barrypicker; 04.01.2020

Небольшая вариация других скриптов здесь приведена ниже. Он установит учетные данные для любых/всех служб, работающих под данной учетной записью. Он попытается перезапустить службу только в том случае, если она уже запущена, чтобы мы случайно не запустили службу, которая была остановлена ​​по какой-то причине. Сценарий должен запускаться из оболочки с повышенными правами (если сценарий начинает сообщать вам о ReturnValue = 2, вы, вероятно, запускаете его без повышенных прав). Некоторые примеры использования:

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

    .\set-servicecredentials.ps1 -password p@ssw0rd

  • все службы, работающие от имени пользователя: somedomain\someuser на хосте somehost.somedomain:

    .\set-servicecredentials.ps1 somehost.somedomain somedomain\someuser p@ssw0rd

Set-ServiceCredentials.ps1:

param (
  [alias('computer', 'c')]
  [string] $computerName = $env:COMPUTERNAME,

  [alias('username', 'u')]
  [string] $serviceUsername = "$env:USERDOMAIN\$env:USERNAME",

  [alias('password', 'p')]
  [parameter(mandatory=$true)]
  [string] $servicePassword
)
Invoke-Command -ComputerName $computerName -Script {
  param(
    [string] $computerName,
    [string] $serviceUsername,
    [string] $servicePassword
  )
  Get-WmiObject -ComputerName $computerName -Namespace root\cimv2 -Class Win32_Service | Where-Object { $_.StartName -eq $serviceUsername } | ForEach-Object {
    Write-Host ("Setting credentials for service: {0} (username: {1}), on host: {2}." -f $_.Name, $serviceUsername, $computerName)
    $change = $_.Change($null, $null, $null, $null, $null, $null, $serviceUsername, $servicePassword).ReturnValue
    if ($change -eq 0) {
      Write-Host ("Service Change() request accepted.")
      if ($_.Started) {
        $serviceName = $_.Name
        Write-Host ("Restarting service: {0}, on host: {1}, to implement credential change." -f $serviceName, $computerName)
        $stop = ($_.StopService()).ReturnValue
        if ($stop -eq 0) {
          Write-Host -NoNewline ("StopService() request accepted. Awaiting 'stopped' status.")
          while ((Get-WmiObject -ComputerName $computerName -Namespace root\cimv2 -Class Win32_Service -Filter "Name='$serviceName'").Started) {
            Start-Sleep -s 2
            Write-Host -NoNewline "."
          }
          Write-Host "."
          $start = $_.StartService().ReturnValue
          if ($start -eq 0) {
            Write-Host ("StartService() request accepted.")
          } else {
            Write-Host ("Failed to start service. ReturnValue was '{0}'. See: http://msdn.microsoft.com/en-us/library/aa393660(v=vs.85).aspx" -f $start) -ForegroundColor "red"
          }
        } else {
          Write-Host ("Failed to stop service. ReturnValue was '{0}'. See: http://msdn.microsoft.com/en-us/library/aa393673(v=vs.85).aspx" -f $stop) -ForegroundColor "red"
        }
      }
    } else {
      Write-Host ("Failed to change service credentials. ReturnValue was '{0}'. See: http://msdn.microsoft.com/en-us/library/aa384901(v=vs.85).aspx" -f $change) -ForegroundColor "red"
    }
  }
} -Credential "$env:USERDOMAIN\$env:USERNAME" -ArgumentList $computerName, $serviceUsername, $servicePassword
person grenade    schedule 01.09.2014
comment
@Kiquenet Я изменил сценарий, чтобы вы запрашивали учетные данные для удаленного хоста. - person grenade; 17.10.2014

Учитывая, что в этом классе:

$class=[WMICLASS]'\\.\root\Microsoft\SqlServer\ComputerManagement:SqlService'

есть метод с именем setserviceaccount(), может быть этот script сделает то, что вы хотите:

# Copyright Buck Woody, 2007
# All scripts provided AS-IS. No functionality is guaranteed in any way.
# Change Service Account name and password using PowerShell and WMI
$class = Get-WmiObject -computername "SQLVM03-QF59YPW" -namespace
root\Microsoft\SqlServer\ComputerManagement -class SqlService

#This remmed out part shows the services - I'll just go after number 6 (SQL
#Server Agent in my case):
# foreach ($classname in $class) {write-host $classname.DisplayName}
# $class[6].DisplayName
stop-service -displayName $class[6].DisplayName

# Note: I recommend you make these parameters, so that you don't store
# passwords. At your own risk here!
$class[6].SetServiceAccount("account", "password")
start-service -displayName $class[6].DisplayName
person VonC    schedule 24.11.2008

Данные ответы делают работу.

Хотя есть еще одна важная деталь; чтобы изменить учетные данные и успешно запустить службу, сначала необходимо предоставить этой учетной записи пользователя разрешения на «Вход в качестве службы».

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

$svc=gwmi win32_service -filter 'Service Name'

$svc.change($null,$null,$null,$null,$null,$null,'.\username','password',$null,$null,$null)
person Syed Waqas    schedule 13.04.2018
comment
ошибка gwmi: неверный запрос выберите * из win32_service, где myservice - person Blue Clouds; 19.06.2020

$svc = Get-WmiObject win32_service -filter "name='serviceName'"

положение имени пользователя и пароля может измениться, поэтому попробуйте эту строку, чтобы найти правильное место$svc.GetMethodParameters("change")

$svc.change($null,$null,$null,$null,$null,$null,$null,$null,$null,"admin-username","admin-password")
person Blue Clouds    schedule 23.06.2020

Просто сделайте комментарий @alastairs более заметным: 6-й параметр должен быть $false вместо $null, когда вы используете учетные записи домена:

$service = Get-WMIObject -class Win32_Service -filter 'Service Name'
$service.change($null, $null, $null, $null, $null, $false, "DOMAIN\account", "mypassword")

Без этого работало у 4/5 сервисов, которые я пробовал менять, но некоторые отказывались меняться (ошибка 21).

person Silex    schedule 16.03.2021

То, что я не могу найти в стеке PS по умолчанию, я нахожу реализованным в Carbon:

http://get-carbon.org/help/Install-Service.html

http://get-carbon.org/help/Carbon_Service.html (только для Carbon 2.0) )

person MoonStom    schedule 20.04.2015

Пример конфигурации СК. Сначала разрешить изменение доступа к определенной целевой папке, а затем использовать заблокированную учетную запись «локальной службы». Я бы использовал set-service -credential, если бы у меня везде была PS 6 или выше.

icacls c:\users\myuser\appdata\roaming\fahclient /grant "local service:(OI)(CI)(M)"
sc config "FAHClient" obj="NT AUTHORITY\LocalService"
person js2010    schedule 30.04.2020