【发布时间】:2012-04-26 22:48:50
【问题描述】:
我遇到了这个似乎可以工作的班轮:
stop-service -inputobject $(get-service -ComputerName remotePC -Name Spooler)
谁能解释原因,因为我认为 stop-service 不起作用,除非您使用远程处理或者它发生在本地主机上。
【问题讨论】:
标签: powershell
我遇到了这个似乎可以工作的班轮:
stop-service -inputobject $(get-service -ComputerName remotePC -Name Spooler)
谁能解释原因,因为我认为 stop-service 不起作用,除非您使用远程处理或者它发生在本地主机上。
【问题讨论】:
标签: powershell
Get-Service 的输出是一个可以在远程计算机上运行的System.ServiceProcess.ServiceController .NET 类。我不知道它是如何做到这一点的——可能是 DCOM 或 WMI。一旦你从Get-Service 获得了其中一个,它就可以传递给Stop-Service,它很可能只是在这个对象上调用Stop() 方法。这会停止远程机器上的服务。事实上,您也可以这样做:
(get-service -ComputerName remotePC -Name Spooler).Stop()
【讨论】:
.WaitForStatus method
感谢大家对这个问题的贡献,我想出了以下脚本。更改 $SvcName 和 $SvrName 的值以满足您的需要。如果远程服务已停止,此脚本将启动它,如果已启动,则将其停止。它使用酷炫的.WaitForStatus 方法等待服务响应。
#Change this values to suit your needs:
$SvcName = 'Spooler'
$SvrName = 'remotePC'
#Initialize variables:
[string]$WaitForIt = ""
[string]$Verb = ""
[string]$Result = "FAILED"
$svc = (get-service -computername $SvrName -name $SvcName)
Write-host "$SvcName on $SvrName is $($svc.status)"
Switch ($svc.status) {
'Stopped' {
Write-host "Starting $SvcName..."
$Verb = "start"
$WaitForIt = 'Running'
$svc.Start()}
'Running' {
Write-host "Stopping $SvcName..."
$Verb = "stop"
$WaitForIt = 'Stopped'
$svc.Stop()}
Default {
Write-host "$SvcName is $($svc.status). Taking no action."}
}
if ($WaitForIt -ne "") {
Try { # For some reason, we cannot use -ErrorAction after the next statement:
$svc.WaitForStatus($WaitForIt,'00:02:00')
} Catch {
Write-host "After waiting for 2 minutes, $SvcName failed to $Verb."
}
$svc = (get-service -computername $SvrName -name $SvcName)
if ($svc.status -eq $WaitForIt) {$Result = 'SUCCESS'}
Write-host "$Result`: $SvcName on $SvrName is $($svc.status)"
}
当然,您运行它的帐户需要适当的权限才能访问远程计算机以及启动和停止服务。当对旧的远程机器执行此操作时,您可能首先必须在旧机器上安装 WinRM 3.0。
【讨论】:
根据内置的 Powershell 示例,这是 Microsoft 建议的。经过测试和验证:
停止:
(Get-WmiObject Win32_Service -filter "name='IPEventWatcher'" -ComputerName Server01).StopService()
开始:
(Get-WmiObject Win32_Service -filter "name='IPEventWatcher'" -ComputerName Server01).StartService()
【讨论】:
这对我有用,但我用它作为开始。 powershell 输出, 等待服务完成启动几次然后完成,然后远程服务器上的 get-service 显示服务已启动。
**start**-service -inputobject $(get-service -ComputerName remotePC -Name Spooler)
【讨论】:
另一种选择;使用invoke-command:
cls
$cred = Get-Credential
$server = 'MyRemoteComputer'
$service = 'My Service Name'
invoke-command -Credential $cred -ComputerName $server -ScriptBlock {
param(
[Parameter(Mandatory=$True,Position=0)]
[string]$service
)
stop-service $service
} -ArgumentList $service
注意:要使用此选项,您需要在远程计算机上安装 PowerShell,并让防火墙允许请求通过,并让 Windows 远程管理服务在目标计算机上运行。您可以通过直接在目标机器上运行以下脚本来配置防火墙(一次性任务):Enable-PSRemoting -force。
【讨论】:
你也可以(Get-Service -Name "what ever" - ComputerName RemoteHost).Status = "Stopped"
【讨论】:
$s = (Get-Service -Computername RemoteHost -Name MyService),然后执行$s.Stop()。然后我做了Write-host $($s.Status) 并且服务仍在运行,但是如果我等待 10 秒让服务停止,然后再次执行 $s=(Get-Service ... 和 Write-host $($s.Status),它返回状态为“已停止”跨度>
您可以只运行一个 foreach 并启用日志记录。 如果出现问题,控制台会显示,您可以查看日志。
这样,您就可以单独处理错误。
我认为这种方式比为验证部分运行测试网络连接效果更好,因为防火墙规则可以创建值 false。
对于此示例,您使用列 ServerName 定义了一个 csv 文件,使用 servername.contoso.com 填充列
$ServerList = "$PSScriptRoot\Serverlist.csv"
$Transcriptlog = "$PSScriptRoot\Transcipt.txt"
Start-Transcript -Path $Transcriptlog -Force
Get-Date -Format "yyyy/MM/dd HH:mm"
Try
{ # Start Try
$ImportServerList = Import-Csv $ServerList -Encoding UTF8 | ForEach-Object { # Start Foreach
New-Object PsObject -Prop @{ # Start New-Object
ServerName = $_.ServerName } # End NewObject
Invoke-Command -ComputerName $_.ServerName -ErrorAction Continue -ScriptBlock { # Start ScriptBlock
# Disable Service PrintSpooler
Get-Service -Name Spooler | Stop-Service -Force
} # End ScriptBlock
} # End Foreach
} # End Try
Catch
{ # Start Catch
Write-Warning -Message "## ERROR## "
Write-Warning -Message "## Script could not start ## "
Write-Warning $Error[0]
} # End Catch
Stop-Transcript
【讨论】:
stop-service -inputobject $(get-service -ComputerName remotePC -Name Spooler)
由于您的变量而失败
-ComputerName remotePC 需要是变量 $remotePC 或字符串 "remotePC"
-Name Spooler(spooler 也是一样)
【讨论】:
据我所知,我现在无法验证,您无法使用 Stop-Service cmdlet 或 .Net 停止远程服务,它不受支持。
是的,它可以工作,但它会停止本地计算机上的服务,而不是远程计算机上的服务。
现在,如果上述情况正确,则无需启用远程处理或 wmi,您可以使用 AT 在远程系统上设置计划作业,该作业在本地运行 Stop-Service。
【讨论】: