使用PowerShell运行命令
我想制作一个脚本,如果我在我的机器上打开它(作为管理员),它将在不同的机器上运行命令(不输入凭据)。 我曾经制作一个脚本来重新启动服务。我是这样做的:使用PowerShell运行命令,powershell,cmd,command,Powershell,Cmd,Command,我想制作一个脚本,如果我在我的机器上打开它(作为管理员),它将在不同的机器上运行命令(不输入凭据)。 我曾经制作一个脚本来重新启动服务。我是这样做的: $out = "lokation\output_NoService.txt" Clear-Content $out $data = Get-Content "lokation\input_PCs.txt" foreach ($line in $data) { $computer = $line.Split(":")[0] $S
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer = $line.Split(":")[0]
$ServiceName = $line.Split(":")[1]
if ($sObj = Get-Service-COmputerName $Computer -Name $ServiceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $ServiceName on $computer"
} else {
Write-Host "$ServiceName is not running on $computer"
Add-Content $out "$computer;$ServiceName"
}
}
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
# if needed, you can pass Credentials too
Restart-RemoteService -ComputerName $computer -ServiceName $serviceName -ErrorFile $out -Verbose
}
input_PCs.txt
包含机器名和要重新启动的服务的名称。
例如:PCName:Servicename
这就是我想从txt扫描PC并在txt格式的机器上运行命令的方式
例如,这样的命令
从c驱动器运行example.exe+参数。
因此:C:\example.exe-paramaters
类似的东西
foreach($line in $data) {
$computer = $line.split(":")[0]
Invoke-Command -ComputerName $computer -ScriptBlock {C:\example.exe -parameters}
}
为了使其正常工作,远程计算机上需要有example.exe。如果情况还不是这样,在上面介绍之前,您可以添加如下内容
if (!(Test-Path -Path "\\$computer\c$\example.exe")) {
Copy-Item -Path "X:\path_to_file\example.exe" -Destination "\\$computer\c$" -Force
}
如果您不想让它请求任何凭据,请确保您的Powershell会话是在您的管理员用户下启动的,该用户可以访问所有计算机的c驱动器。类似的内容
foreach($line in $data) {
$computer = $line.split(":")[0]
Invoke-Command -ComputerName $computer -ScriptBlock {C:\example.exe -parameters}
}
为了使其正常工作,远程计算机上需要有example.exe。如果情况还不是这样,在上面介绍之前,您可以添加如下内容
if (!(Test-Path -Path "\\$computer\c$\example.exe")) {
Copy-Item -Path "X:\path_to_file\example.exe" -Destination "\\$computer\c$" -Force
}
如果您不希望它请求任何凭据,请确保您的Powershell会话是在您的管理员用户下启动的,该用户可以访问所有计算机的c驱动器。没有用于管理远程计算机上的服务的-ComputerName
参数。要远程使用该cmdlet,可以使用
Invoke-Command -Computername $computer -ArgumentList $ServiceName -ScriptBlock {
param($service)
Restart-Service -Name $service}
编辑
指出从
Get Service
返回的对象包含MachineName
属性。当此对象作为InputObject
参数在以下Restart Service
中使用时,cmdlet将使用该MachineName属性在该远程计算机上重新启动服务
因为我从来没有想过,我一直在用它进行测试,事实上它确实是这样工作的
因此,如果您在远程计算机上有这样做的权限,您的代码(带有更正的ComputerName参数)应按预期工作:
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
if ($sObj = Get-Service -ComputerName $computer -Name $serviceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $serviceName on $computer"
}
else {
Write-Host "Service '$serviceName' cannot be found on computer '$computer'"
Add-Content -Path $out -Value "$computer; $serviceName"
}
}
但是,这不允许添加用户凭据,因为Get Service
不提供credentials
对象。
如果需要使用不同的凭据,可以执行以下操作:
$credential = Get-Credential
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
# unravel the $credential object into plain username and password:
$user = $credential.GetNetworkCredential().UserName
$password = $credential.GetNetworkCredential().Password
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
# create a connection to the remote machine using credentials
net use "\\$computer\c$" $password /USER:$user
if ($sObj = Get-Service -ComputerName $computer -Name $serviceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $serviceName on $computer"
}
else {
Write-Host "Service '$serviceName' cannot be found on computer '$computer'"
Add-Content -Path $out -Value "$computer; $serviceName"
}
}
我能想到的最后一个选项是使用Get WmiObject
cmdlet,为了方便起见,我将其包装在一个自定义函数中:
function Restart-RemoteService {
[CmdletBinding()]
Param(
[Parameter(Position = 0,Mandatory = $true, ValueFromPipelineByPropertyName = $true,ValueFromPipeline = $true)]
[string]$ComputerName,
[Parameter(Position = 1,Mandatory = $true)]
[string]$ServiceName,
[Parameter(Position = 2,Mandatory = $true)]
[string]$ErrorFile
[Parameter(Mandatory = $false)]
[System.Management.Automation.PSCredential]$Credential
)
$wmiParams = @{
'Class' = 'Win32_Service'
'ComputerName' = $ComputerName
'Filter' = "Name='$ServiceName'"
}
if ($Credential) { $wmiParams['Credential'] = $Credential }
$svc = Get-WmiObject @wmiParams
if (!$svc) {
Write-Warning "Service '$ServiceName' cannot be found on computer '$ComputerName'"
Add-Content -Path "lokation\output_NoService.txt" -Value "$ComputerName; $ServiceName"
}
if ($svc.State -eq 'Running') {
Write-Verbose "Stopping service '$ServiceName' on computer '$ComputerName'"
[void]$svc.StopService()
$maxWait = 20
do {
Start-Sleep -Milliseconds 100
$maxWait--
if ($maxWait -le 0) {
Throw "Could not stop service '$ServiceName'"
}
} while (( Get-WmiObject @wmiParams).State -ne 'Stopped')
}
Write-Verbose "Starting service '$ServiceName' on computer '$ComputerName'"
[void]$svc.StartService()
}
然后,您的代码可能如下所示:
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer = $line.Split(":")[0]
$ServiceName = $line.Split(":")[1]
if ($sObj = Get-Service-COmputerName $Computer -Name $ServiceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $ServiceName on $computer"
} else {
Write-Host "$ServiceName is not running on $computer"
Add-Content $out "$computer;$ServiceName"
}
}
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
# if needed, you can pass Credentials too
Restart-RemoteService -ComputerName $computer -ServiceName $serviceName -ErrorFile $out -Verbose
}
没有用于管理远程计算机上的服务的-ComputerName
参数。要远程使用该cmdlet,可以使用
Invoke-Command -Computername $computer -ArgumentList $ServiceName -ScriptBlock {
param($service)
Restart-Service -Name $service}
编辑
指出从
Get Service
返回的对象包含MachineName
属性。当此对象作为InputObject
参数在以下Restart Service
中使用时,cmdlet将使用该MachineName属性在该远程计算机上重新启动服务
因为我从来没有想过,我一直在用它进行测试,事实上它确实是这样工作的
因此,如果您在远程计算机上有这样做的权限,您的代码(带有更正的ComputerName参数)应按预期工作:
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
if ($sObj = Get-Service -ComputerName $computer -Name $serviceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $serviceName on $computer"
}
else {
Write-Host "Service '$serviceName' cannot be found on computer '$computer'"
Add-Content -Path $out -Value "$computer; $serviceName"
}
}
但是,这不允许添加用户凭据,因为Get Service
不提供credentials
对象。
如果需要使用不同的凭据,可以执行以下操作:
$credential = Get-Credential
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
# unravel the $credential object into plain username and password:
$user = $credential.GetNetworkCredential().UserName
$password = $credential.GetNetworkCredential().Password
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
# create a connection to the remote machine using credentials
net use "\\$computer\c$" $password /USER:$user
if ($sObj = Get-Service -ComputerName $computer -Name $serviceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $serviceName on $computer"
}
else {
Write-Host "Service '$serviceName' cannot be found on computer '$computer'"
Add-Content -Path $out -Value "$computer; $serviceName"
}
}
我能想到的最后一个选项是使用Get WmiObject
cmdlet,为了方便起见,我将其包装在一个自定义函数中:
function Restart-RemoteService {
[CmdletBinding()]
Param(
[Parameter(Position = 0,Mandatory = $true, ValueFromPipelineByPropertyName = $true,ValueFromPipeline = $true)]
[string]$ComputerName,
[Parameter(Position = 1,Mandatory = $true)]
[string]$ServiceName,
[Parameter(Position = 2,Mandatory = $true)]
[string]$ErrorFile
[Parameter(Mandatory = $false)]
[System.Management.Automation.PSCredential]$Credential
)
$wmiParams = @{
'Class' = 'Win32_Service'
'ComputerName' = $ComputerName
'Filter' = "Name='$ServiceName'"
}
if ($Credential) { $wmiParams['Credential'] = $Credential }
$svc = Get-WmiObject @wmiParams
if (!$svc) {
Write-Warning "Service '$ServiceName' cannot be found on computer '$ComputerName'"
Add-Content -Path "lokation\output_NoService.txt" -Value "$ComputerName; $ServiceName"
}
if ($svc.State -eq 'Running') {
Write-Verbose "Stopping service '$ServiceName' on computer '$ComputerName'"
[void]$svc.StopService()
$maxWait = 20
do {
Start-Sleep -Milliseconds 100
$maxWait--
if ($maxWait -le 0) {
Throw "Could not stop service '$ServiceName'"
}
} while (( Get-WmiObject @wmiParams).State -ne 'Stopped')
}
Write-Verbose "Starting service '$ServiceName' on computer '$ComputerName'"
[void]$svc.StartService()
}
然后,您的代码可能如下所示:
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer = $line.Split(":")[0]
$ServiceName = $line.Split(":")[1]
if ($sObj = Get-Service-COmputerName $Computer -Name $ServiceName -ErrorAction SilentlyContinue) {
Restart-Service -InputObj $sObj
Write-Host "Restarting $ServiceName on $computer"
} else {
Write-Host "$ServiceName is not running on $computer"
Add-Content $out "$computer;$ServiceName"
}
}
$out = "lokation\output_NoService.txt"
Clear-Content $out
$data = Get-Content "lokation\input_PCs.txt"
foreach ($line in $data) {
$computer, $serviceName = $line -split ':', 2
# if needed, you can pass Credentials too
Restart-RemoteService -ComputerName $computer -ServiceName $serviceName -ErrorFile $out -Verbose
}
对我来说,它看起来应该像预期的那样工作。。。您的问题是什么?除了其他事项外,您需要在>>
Get Service COmputerName
中的第二个连字符前添加一个空格。对我来说,它看起来应该可以正常工作。。。你有什么问题?除了其他事情,您需要在>>Get Service COmputerName
中的第二个连字符前面添加一个空格,我认为上一个Get Service
调用中的对象将具有.MachineName
属性,这意味着-InputObject
参数将使用该属性联系远程系统。我无法测试[只有一个系统],但我记得在有关该主题的帖子中,当对远程系统使用时,Get Service
管道连接到Restart Service
。@Lee_Dailey有趣!我必须承认我从来没有想过。。我现在在手机上,所以无法测试。我期待着看到你的结果。。。[grin]@Lee_Dailey需要做一些工作来测试这一点,但您是对的,MachineName
属性由重新启动服务
cmdlet使用,前提是获取服务
返回的对象是通过参数-InputObject
提供的。在处理这个问题的同时,我还添加了一个使用getwmiobject
的方法。谢谢尼托![grin]如果您想了解完整性,还可以使用调用命令
,或新建PSSession
和输入PSSession
。。。但这就是编写完整教程的过程……我认为上一个Get Service
调用中的对象将具有.MachineName
属性,这意味着-InputObject
参数将使用该属性联系远程系统。我无法测试[只有一个系统],但我记得在有关该主题的帖子中,当对远程系统使用时,Get Service
管道连接到Restart Service
。@Lee_Dailey有趣!我必须承认我从来没有想过。。我现在在手机上,所以无法测试。我期待着看到你的结果。。。[grin]@Lee_Dailey需要做一些工作来测试这一点,但您是对的,MachineName
属性由Restart-Service
cmdlet使用,前提是Get-Service
返回的对象是通过参数-InputOb提供的