Powershell 工作流程与 "foreach -parallel" 和 Invoke-AZVMRunCommand- 如何获得结果?



我在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中运行该脚本。

最新更新