Powershell Runspace Job 내에서 Server 2012R2 호스팅 VM에 대해 Get-VHD 파일 크기가 0을 반환하는 이유는 무엇입니까?

Powershell Runspace Job 내에서 Server 2012R2 호스팅 VM에 대해 Get-VHD 파일 크기가 0을 반환하는 이유는 무엇입니까?

Hyper-V 클러스터에서 호스팅되는 VM의 CSV를 만드는 스크립트가 있습니다. 훌륭하게 작동하고 있으며 각 VM을 하나의 작업으로 분리하는 기능까지 갖추고 있습니다!

참고 사항: 일정을 보다 효율적으로 수행하는 방법에 대한 조언은 마음에 들지 않습니다. 주요 문제는 일부 클러스터는 WS 2016이고 다른 클러스터는 이전 Hyper-V PowerShell 모듈이 필요한 WS 2012R2라는 것입니다. 다양한 모듈을 병렬화하는 방법을 잘 모르기 때문에 각 Hyper-V 노드에 대한 VM 목록을 가져와서 병렬화한 후 다음 노드에서 필요할 경우 모듈을 변경합니다.

어쨌든, 내 문제. 여기 내 스크립트가 있습니다.

$numThreads = 4

$ScriptBlock = {
    Param (
        [string]$Cluster,
        [string]$Node,
        $VM
    )

    If ($ADComputer = (Get-ADComputer $VM.Name -Properties OperatingSystem)) {
        $OS = $ADComputer.OperatingSystem
    }
    Else {
        $OS = 'Unknown (not on domain)'
    }

    try {
        Return [pscustomobject] @{
            Cluster               = $Cluster
            Node                  = $Node
            Name                  = $VM.Name
            OS                    = $OS
            State                 = $VM.State
            Status                = $VM.Status
            Uptime                = "{0:dd} days {0:hh} hours" -f $VM.Uptime
            CPUUsage              = $VM.CPUUsage
            ProcessorCount        = $VM.ProcessorCount
            'MemoryDemand (GB)'   = [math]::Round( $VM.MemoryDemand / 1GB, 2 )
            'MemoryAssigned (GB)' = [math]::Round( $VM.MemoryAssigned / 1GB, 2 )
            'VHD Size (GB)'       = [math]::Round( ((Get-VHD -ComputerName $Node -VMId $VM.Id).FileSize | Measure-Object -Sum).Sum / 1GB, 2 )
            Version               = $VM.Version
            'VLAN IDs'            = ($VM | Select-Object -ExpandProperty NetworkAdapters | Select-Object -ExpandProperty VlanSetting).AccessVlanId -Join ", "
            'IP Addresses'        = ($VM | Select-Object -ExpandProperty NetworkAdapters).IPAddresses -Join ", "
        }
    }
    catch {
        Return [pscustomobject] @{
            Cluster = $Cluster
            Node    = $Node
            Name    = $VM.Name
            State   = "Script Fail"
            Status  = $_.Exception.Message
        }
    }
}

$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $numThreads)
$RunspacePool.Open()

$Jobs = @()
$VMInfoList = @()

ForEach ($Cluster in 'USHOMECLU0', 'USHOMECLU1') {
    If ((Get-ADComputer $Cluster -Property OperatingSystem).OperatingSystem -Match '2016') {
        Remove-Module Hyper-V
        Import-Module Hyper-V -RequiredVersion 2.0.0.0
    }
    Else {
        Remove-Module Hyper-V
        Import-Module Hyper-V -RequiredVersion 1.1
    }
    ForEach ($Node in Get-ClusterNode -Cluster $Cluster) {
        Get-VM -ComputerName $Node | ForEach-Object {
            $Job = [powershell]::Create().AddScript($ScriptBlock).AddParameter("Cluster", $Cluster).AddParameter("Node", $Node).AddParameter("VM", $_)
            $Job.RunspacePool = $RunspacePool
            $Jobs += New-Object PSObject -Property @{
                Job    = $Job
                Result = $Job.BeginInvoke()
            }
        }
    }
}

# EndInvoke returns the objects from the background threads
ForEach ($Job in $Jobs) {
    $VMInfoList += $Job.Job.EndInvoke($Job.Result)
}

$VMInfoList | Export-Csv -NoTypeInformation C:\PSReports_vms.csv

내가 가진 문제는 Windows Server 2012R2 노드의 VM에 대한 작업이 이에 대해 항상 0을 반환한다는 것입니다.

        'VHD Size'       = ((Get-VHD -ComputerName $Node -VMId $VM.Id).FileSize | Measure-Object -Sum).Sum

그러나 Windows Server 2016 노드의 경우 모든 VM이 적절한 값을 반환합니다. 또한 흥미로운 점은 해당 Server 2012R2 호스팅 VM의 VHD 크기에 할당되는 정확한 표현식을 캡처하고(변수를 직접 문자열로 대체) 작업에 대한 스크립트 블록 외부에서 실행하면 정확한 값을 얻을 수 있다는 것입니다.

관련 정보