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。