我在Azure中有很多虚拟机,我想对它们运行相同的脚本。由于原因,我不能使用powershell 7,所以我必须使用powershell 5。这意味着我可以使用";foreach-parallel";,但不是";前臂平行";。所以它可以工作,但需要一个工作流。
我有下面的工作流程,它将获取特定租户/环境中的服务器列表,然后运行foreach-parallel来同时针对每个服务器运行脚本。
我遇到的问题是它似乎有效,但我得到的结果是:
Microsoft.Azure.Commands.Compute.Automation.Models.PSRunCommandResult
blah
这不是实际的结果(在这种情况下,这将是时间(。因为这是在一个工作流程中,所以公布细节是……痛苦的。如何获得结果?它似乎在运行,没有错误,但我无法计算结果。谢谢
$out上的get会员给予:
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
ToString Method string ToString(), string ToString(string format, System.IFormatProvider formatProvider), string IFormattable.ToString(string format, System.I...
PSComputerName NoteProperty string PSComputerName=localhost
PSShowComputerName NoteProperty bool PSShowComputerName=True
PSSourceJobInstanceId NoteProperty guid PSSourceJobInstanceId=0870d1ff-1234-5678-014e-2e123456c7d8
Capacity Property System.Int32 {get;set;}
Count Property System.Int32 {get;set;}
EndTime Property {get;set;}
Error Property {get;set;}
Item Property {get;set;}
Name Property {get;set;}
Output Property {get;set;}
StartTime Property {get;set;}
Status Property System.String {get;set;}
Value Property Deserialized.System.Collections.Generic.List`1[[Microsoft.Azure.Management.Compute.Models.InstanceViewStatus, Microsoft.Azure.Management.Compu...
Microsoft.Azure.Commands.Compute.Automation.Models.PSRunCommandResult
这是我正在运行的脚本:
#for some reason you need to disconnect from one and then connect to the other, can't run two at once.
disconnect-azaccount
connect-azaccount -Tenant "mytenantid"
#get all the dev Windows VM servers in the current tenant that are turned on.
$serverinfo = @()
Get-AzContext -ListAvailable |where-object {$_.Name -like "*Dev*"}| %{
$_|select-azcontext
$serverinfo += get-azvm -status | Where-Object {$_.PowerState -eq "VM running" -and $_.StorageProfile.OSDisk.OSType -eq "Windows"}
}
#honestly, for the test I filtered down to the jumpboxes.
$serverinfo2 = $serverinfo|where {$_.Name -like "*jumpbox*"}
#workflows are needed; can't run foreach -parallel otherwise.
Workflow TestParallel{
#need to pass in the details, it can't reach the $serverinfo2 otherwise.
param($listofservers) #take serverinfo2 and make it accessible from within the workflow.
$test=@()
#need to set the proper context
Get-AzContext -ListAvailable |where-object {$_.Name -like "*Dev*"}| select-azcontext
#now we run each of these at the same time. Foreach-parallel requires 7, but we can do foreach -parallel within powershell 4 workflows.
Foreach -parallel($server in $listofservers){
#now that the script is on there, run the command locally.
$out = Invoke-AzVMRunCommand `
-ResourceGroupName $server.ResourceGroupName `
-Name $server.name `
-CommandId 'RunPowerShellScript' `
-ScriptString "$dt = gwmi win32_localtime; New-Object DateTime $dt.year,$dt.month,$dt.day,$dt.hour,$dt.minute, $dt.second"
#scriptstring is a newer command, added in july 2022
#Formating the Output with the VM name. Value[0].Message contains the results from running the script.
#export it to a variable that will survive the foreach
#$WORKFLOW:test += $server.Name + " " + $out.Value[0].Message
$WORKFLOW:test += $out.Value[1].Message #appears to be 1 now, using " -scriptstring"
#writing it locally to see if it shows up
"$out"
}
[array]$resultsArray = @($test)
write-output ("blah " + $test[0])
$resultsArray
}
TestParallel $serverinfo2
我会避免使用"foreach-平行;以及";工作流";由于这里提到的并行处理和工作流的当前限制,因此我建议使用本答案中提到的第一种方法,即将脚本存储在存储帐户中,然后在foreach循环的帮助下,使用Invoke-AzVMRunCommand cmdlet在所有虚拟机中远程运行该脚本,foreach循环基本上在所有VM中运行该脚本。