用于更改服务帐户的Powershell脚本

时间:2020-12-15 15:34:20

Does anyone have a Powershell script to change the credentials used by a Windows service?

有没有人有Powershell脚本来更改Windows服务使用的凭据?

8 个解决方案

#1


36  

Bit easier - use WMI.

更容易 - 使用WMI。

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

Change the service name appropriately in the filter; set the remote computer name appropriately.

在过滤器中适当更改服务名称;适当地设置远程计算机名称。

#2


26  

I wrote a function for PowerShell that changes the username, password, and restarts a service on a remote computer (you can use localhost if you want to change the local server). I've used this for monthly service account password resets on hundreds of servers.

我为PowerShell编写了一个更改用户名,密码并在远程计算机上重新启动服务的函数(如果要更改本地服务器,可以使用localhost)。我已经将它用于数百台服务器上的每月服务帐户密码重置。

You can find a copy of the original at http://www.send4help.net/change-remote-windows-service-credentials-password-powershel-495

您可以在http://www.send4help.net/change-remote-windows-service-credentials-password-powershel-495找到原件的副本。

It also waits until the service is fully stopped to try to start it again, unlike one of the other answers.

它还等待服务完全停止以尝试再次启动它,这与其他答案不同。

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()
}

#3


10  

I created a text file "changeserviceaccount.ps1" containing the following script:

我创建了一个包含以下脚本的文本文件“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()

I used this as part of by post-build command line during the development of a windows service:

我在开发Windows服务期间使用它作为post-build命令行的一部分:

Visual Studio: Project properties\Build Events

Visual Studio:项目属性\构建事件

Pre-build event command line:

预构建事件命令行:

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

Post-build event command line:

构建后事件命令行:

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

#4


4  

A slight variation on the other scripts here, is below. This one will set credentials for any/all services running under a given login account. It will only attempt to restart the service if it was already running, so that we don't accidentally start a service that was stopped for a reason. The script has to be run from and elevated shell (if the script starts telling you about ReturnValue = 2, you're probably running it un-elevated). Some usage examples are:

这里的其他脚本略有不同,如下所示。这个将为在给定登录帐户下运行的任何/所有服务设置凭据。如果服务已经运行,它将只尝试重新启动服务,这样我们就不会意外启动因某种原因而停止的服务。该脚本必须从shell运行并升级shell(如果脚本开始告诉您有关ReturnValue = 2的信息,那么您可能无法提升它)。一些用法示例是:

  • all services running as the currently logged in user, on the local host:

    在本地主机上以当前登录用户身份运行的所有服务:

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

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

  • all services running as user: somedomain\someuser on host somehost.somedomain:

    以用户身份运行的所有服务:somedomain \ someuser on host somehost.somedomain:

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

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

Set-ServiceCredentials.ps1:

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

#5


3  

Considering that whithin this class:

考虑到这个类:

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

there's a method named setserviceaccount(), may be this script will do what you want:

有一个名为setserviceaccount()的方法,可能是这个脚本会做你想要的:

# 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

#6


0  

What I cannot find in the default PS stack, I find it implemented in Carbon:

我在默认的PS堆栈中找不到,我发现它在Carbon中实现:

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

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

http://get-carbon.org/help/Carbon_Service.html (Carbon 2.0 only)

http://get-carbon.org/help/Carbon_Service.html(仅限Carbon 2.0)

#7


0  

The PowerShell 6 version of Set-Service now has the -Credential parameter.

PowerShell 6版本的Set-Service现在具有-Credential参数。

Here is an example:

这是一个例子:

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

At this point, it is only available via download via GitHub.

此时,只能通过GitHub下载。

Enjoy!

请享用!

#8


0  

The given answers do the job.

给出的答案可以胜任。

Although, there is another important detail; in order to change the credentials and run the service successfully, you first have to grant that user account permissions to 'Log on as a Service'.

虽然,还有另一个重要的细节;为了更改凭据并成功运行服务,首先必须将该用户帐户的权限授予“作为服务登录”。

To grant that privilege to a user, use the Powershell script provided here by just providing the username of the account and then run the other commands to update the credentials for a service as mentioned in the other answers, i.e.,

要将该权限授予用户,请使用此处提供的Powershell脚本,只需提供帐户的用户名,然后运行其他命令以更新其他答案中提到的服务凭据,即

$svc=gwmi win32_service -filter 'Service Name'

$svc.change($null,$null,$null,$null,$null,$null,'.\username','password',$null,$null,$null)

#1


36  

Bit easier - use WMI.

更容易 - 使用WMI。

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

Change the service name appropriately in the filter; set the remote computer name appropriately.

在过滤器中适当更改服务名称;适当地设置远程计算机名称。

#2


26  

I wrote a function for PowerShell that changes the username, password, and restarts a service on a remote computer (you can use localhost if you want to change the local server). I've used this for monthly service account password resets on hundreds of servers.

我为PowerShell编写了一个更改用户名,密码并在远程计算机上重新启动服务的函数(如果要更改本地服务器,可以使用localhost)。我已经将它用于数百台服务器上的每月服务帐户密码重置。

You can find a copy of the original at http://www.send4help.net/change-remote-windows-service-credentials-password-powershel-495

您可以在http://www.send4help.net/change-remote-windows-service-credentials-password-powershel-495找到原件的副本。

It also waits until the service is fully stopped to try to start it again, unlike one of the other answers.

它还等待服务完全停止以尝试再次启动它,这与其他答案不同。

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()
}

#3


10  

I created a text file "changeserviceaccount.ps1" containing the following script:

我创建了一个包含以下脚本的文本文件“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()

I used this as part of by post-build command line during the development of a windows service:

我在开发Windows服务期间使用它作为post-build命令行的一部分:

Visual Studio: Project properties\Build Events

Visual Studio:项目属性\构建事件

Pre-build event command line:

预构建事件命令行:

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

Post-build event command line:

构建后事件命令行:

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

#4


4  

A slight variation on the other scripts here, is below. This one will set credentials for any/all services running under a given login account. It will only attempt to restart the service if it was already running, so that we don't accidentally start a service that was stopped for a reason. The script has to be run from and elevated shell (if the script starts telling you about ReturnValue = 2, you're probably running it un-elevated). Some usage examples are:

这里的其他脚本略有不同,如下所示。这个将为在给定登录帐户下运行的任何/所有服务设置凭据。如果服务已经运行,它将只尝试重新启动服务,这样我们就不会意外启动因某种原因而停止的服务。该脚本必须从shell运行并升级shell(如果脚本开始告诉您有关ReturnValue = 2的信息,那么您可能无法提升它)。一些用法示例是:

  • all services running as the currently logged in user, on the local host:

    在本地主机上以当前登录用户身份运行的所有服务:

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

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

  • all services running as user: somedomain\someuser on host somehost.somedomain:

    以用户身份运行的所有服务:somedomain \ someuser on host somehost.somedomain:

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

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

Set-ServiceCredentials.ps1:

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

#5


3  

Considering that whithin this class:

考虑到这个类:

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

there's a method named setserviceaccount(), may be this script will do what you want:

有一个名为setserviceaccount()的方法,可能是这个脚本会做你想要的:

# 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

#6


0  

What I cannot find in the default PS stack, I find it implemented in Carbon:

我在默认的PS堆栈中找不到,我发现它在Carbon中实现:

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

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

http://get-carbon.org/help/Carbon_Service.html (Carbon 2.0 only)

http://get-carbon.org/help/Carbon_Service.html(仅限Carbon 2.0)

#7


0  

The PowerShell 6 version of Set-Service now has the -Credential parameter.

PowerShell 6版本的Set-Service现在具有-Credential参数。

Here is an example:

这是一个例子:

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

At this point, it is only available via download via GitHub.

此时,只能通过GitHub下载。

Enjoy!

请享用!

#8


0  

The given answers do the job.

给出的答案可以胜任。

Although, there is another important detail; in order to change the credentials and run the service successfully, you first have to grant that user account permissions to 'Log on as a Service'.

虽然,还有另一个重要的细节;为了更改凭据并成功运行服务,首先必须将该用户帐户的权限授予“作为服务登录”。

To grant that privilege to a user, use the Powershell script provided here by just providing the username of the account and then run the other commands to update the credentials for a service as mentioned in the other answers, i.e.,

要将该权限授予用户,请使用此处提供的Powershell脚本,只需提供帐户的用户名,然后运行其他命令以更新其他答案中提到的服务凭据,即

$svc=gwmi win32_service -filter 'Service Name'

$svc.change($null,$null,$null,$null,$null,$null,'.\username','password',$null,$null,$null)