Powershell - 运行 同时在多台计算机上运行脚本
Powershell - run script on multiple computers simultaneously
我正在编写一个脚本来清理旧用户帐户和计算机中的一些数据。
我想 运行 一次在 5 台计算机上的脚本从附件的 PC 列表。
可能吗?
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$host_path = 'Host path'
)
$computer = Get-Content "$host_path"
foreach ($computer in $computer){
Invoke-Command -ComputerName $computer -ScriptBlock { Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject }
Invoke-Command -ComputerName $computer -ScriptBlock { Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug }
Invoke-Command -ComputerName $computer -ScriptBlock { Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug }
}
```
您可以一次将多个计算机名称传递给 Invoke-Command
以实现此目的:
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$host_path = 'Host path'
)
$computerNames = Get-Content $host_path
Invoke-Command -ComputerName $computerNames -ScriptBlock {
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject
Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug
Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug
}
如果要将计算机名称列表一次“分块”到 N 台机器上的批次中,可以这样做:
$computerNames = Get-Content $host_path
$batchSize = 5
while($computerNames.Count -gt 0){
# Pull the first N names from the list
$nextBatch = @($computerNames |Select -First $batchSize)
# Then overwrite the list with any elements _after_ the first N names
$computerNames = @($computerNames |Select -Skip $batchSize)
Write-Host "Executing remote command against $($nextBatch.Count) computers: [$($nextBatch.ForEach({"'$_'"}) -join ', ')]"
# Invoke remoting command against the batch of computer names
Invoke-Command -ComputerName $nextBatch -ScriptBlock {
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject
Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug
Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug
}
}
如果您使用的是 PowerShell 7.x,您可以执行以下操作。
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$host_path = 'Host path'
)
# The default value for ThrottleLimit is 5, but I put it here to show syntax.
# Throttle is the number of concurrent runspaces to use. (ex: do 5 objects at a time)
Get-Content $host_path | Foreach-Object -ThrottleLimit 5 -Parallel -ScriptBlock {
Invoke-Command -ComputerName $_ -ScriptBlock {
Get-WMIObject -class Win32_UserProfile | Where-Object {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject
Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug
Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug
}
}
这将 运行 一次循环 X,X 是您的 -ThrottleLimit
值,默认为 5
。
同样,这仅在 PowerShell 7 中可用,并且不向后兼容 Windows PowerShell。
我正在编写一个脚本来清理旧用户帐户和计算机中的一些数据。 我想 运行 一次在 5 台计算机上的脚本从附件的 PC 列表。 可能吗?
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$host_path = 'Host path'
)
$computer = Get-Content "$host_path"
foreach ($computer in $computer){
Invoke-Command -ComputerName $computer -ScriptBlock { Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject }
Invoke-Command -ComputerName $computer -ScriptBlock { Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug }
Invoke-Command -ComputerName $computer -ScriptBlock { Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug }
}
```
您可以一次将多个计算机名称传递给 Invoke-Command
以实现此目的:
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$host_path = 'Host path'
)
$computerNames = Get-Content $host_path
Invoke-Command -ComputerName $computerNames -ScriptBlock {
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject
Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug
Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug
}
如果要将计算机名称列表一次“分块”到 N 台机器上的批次中,可以这样做:
$computerNames = Get-Content $host_path
$batchSize = 5
while($computerNames.Count -gt 0){
# Pull the first N names from the list
$nextBatch = @($computerNames |Select -First $batchSize)
# Then overwrite the list with any elements _after_ the first N names
$computerNames = @($computerNames |Select -Skip $batchSize)
Write-Host "Executing remote command against $($nextBatch.Count) computers: [$($nextBatch.ForEach({"'$_'"}) -join ', ')]"
# Invoke remoting command against the batch of computer names
Invoke-Command -ComputerName $nextBatch -ScriptBlock {
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject
Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug
Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug
}
}
如果您使用的是 PowerShell 7.x,您可以执行以下操作。
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$host_path = 'Host path'
)
# The default value for ThrottleLimit is 5, but I put it here to show syntax.
# Throttle is the number of concurrent runspaces to use. (ex: do 5 objects at a time)
Get-Content $host_path | Foreach-Object -ThrottleLimit 5 -Parallel -ScriptBlock {
Invoke-Command -ComputerName $_ -ScriptBlock {
Get-WMIObject -class Win32_UserProfile | Where-Object {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))}| Remove-WmiObject
Remove-Item -Path C:\Windows\ccmcache\* -Confirm:$false -Force -Recurse -Debug
Remove-Item -Path C:\ProgramDataE\NomadBranch\* -Confirm:$false -Force -Recurse -Debug
}
}
这将 运行 一次循环 X,X 是您的 -ThrottleLimit
值,默认为 5
。
同样,这仅在 PowerShell 7 中可用,并且不向后兼容 Windows PowerShell。