是否有人使用Powershell脚本来更改Windows服务使用的凭据?
答案 0 :(得分:38)
更容易 - 使用WMI。
$service = gwmi win32_service -computer [computername] -filter "name='whatever'"
$service.change($null,$null,$null,$null,$null,$null,$null,"P@ssw0rd")
在过滤器中适当更改服务名称;适当地设置远程计算机名称。
答案 1 :(得分:32)
我为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()
}
答案 2 :(得分:10)
我创建了一个包含以下脚本的文本文件“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服务期间使用它作为post-build命令行的一部分:
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
答案 3 :(得分:5)
此处的其他脚本略有不同,如下所示。这个将为在给定登录帐户下运行的任何/所有服务设置凭据。如果服务已经运行,它将只尝试重新启动服务,这样我们就不会意外启动因某种原因而停止的服务。该脚本必须从shell运行并提升shell(如果脚本开始告诉您有关ReturnValue = 2
的信息,那么您可能无法提升它)。一些用法示例如下:
在本地主机上以当前登录用户身份运行的所有服务:
.\set-servicecredentials.ps1 -password p@ssw0rd
在主机somedomain\someuser
上以用户身份运行的所有服务:somehost.somedomain
:
.\set-servicecredentials.ps1 somehost.somedomain somedomain\someuser p@ssw0rd
设置-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
答案 4 :(得分:3)
考虑到这个课程:
$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
答案 5 :(得分:1)
PowerShell 6版Set-Service
现在有-Credential
参数。
以下是一个例子:
$creds = Get-Credentials
Set-Service -DisplayName "Remote Registry" -Credentials $creds
此时,只能通过GitHub下载。
享受!
答案 6 :(得分:1)
只是让@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)。
答案 7 :(得分:0)
我在默认PS堆栈中找不到的内容,我发现它在Carbon
中实现:
答案 8 :(得分:0)
给出的答案可以胜任。
虽然,还有另一个重要的细节;为了更改凭据并成功运行服务,您首先必须授予该用户帐户权限“以服务身份登录”。
要将该权限授予用户,请使用提供here的Powershell脚本,只需提供帐户的用户名,然后运行其他命令以更新其他答案中提到的服务凭据,即,
$svc=gwmi win32_service -filter 'Service Name'
$svc.change($null,$null,$null,$null,$null,$null,'.\username','password',$null,$null,$null)
答案 9 :(得分:0)
Sc配置示例。首先允许修改对特定目标文件夹的访问,然后使用锁定的“本地服务”帐户。如果我到处都有PS 6或更高版本,我将使用set-service -credential。
icacls c:\users\myuser\appdata\roaming\fahclient /grant "local service:(OI)(CI)(M)"
sc config "FAHClient" obj="NT AUTHORITY\LocalService"
答案 10 :(得分:0)
$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")