Friday, November 16, 2018

Finding a VM across Hyper-V using PS -AsJob

One thing fantastic about PowerShell is jobs.  They provide a multi-threaded approach to running multiple tasks simultaneously.  Finding a VM across multiple clusters can be difficult if not using additional tooling like MSCVMM.  This provides a quick solution.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
$vmFilter = "regex"
$showDisk = $false

Get-Cluster -Name hvc* -Domain <yourdomain> | Where-Object Name -match "(weash|wephx)" | ForEach-Object {
    
    $cluster = $_.Name

    if (Test-Connection -ComputerName $cluster -Count 1 -ErrorAction SilentlyContinue){

        Get-ClusterNode -Cluster $_.Name -ErrorAction SilentlyContinue | Get-Random | ForEach-Object {

            Invoke-Command -ComputerName $_.Name -ScriptBlock {
                Param($vmFilter,$vmCluster)

                Get-ClusterResource | Where ResourceType -eq 'Virtual Machine' | Where-Object OwnerGroup -match $vmFilter | % {

                    $vm      = $_ | Get-VM 
                    $vmDisks = Get-VHD -ComputerName $vm.ComputerName -VMId $vm.VMId
                    $vmMem   = $vm | Get-VMMemory
                    $vmIP    = $vm | Get-VMNetworkAdapter | Select-Object -ExpandProperty IPAddresses | Select-Object -First 1
                    $vmVLAN  = $vm | Get-VMNetworkAdapterVlan | Select-Object -ExpandProperty AccessVlanId
                    $vmPRD   = $vm | Select -ExpandProperty Notes | ConvertFrom-Json | Select -ExpandProperty ProductCode
                    $vmStop  = $vm.AutomaticStopAction

                    [PSCustomObject]@{
                        Cluster = $vmCluster
                        State   = $vm.State
                        PRDCode = $vmPRD
                        IP      = $vmIP
                        VLAN    = $vmVLAN
                        VM      = $vm
                        Memory  = $vmMem
                        Disks   = $vmDisks
                        StopAct = $vmStop
                    }
                    
                }
        
            } -AsJob -ArgumentList $vmFilter,$cluster
            
        }

    }
    
};Get-Job | Wait-Job; $results = Get-Job | Receive-Job; Get-Job | Remove-Job


$results | ForEach-Object{

    $diskCount = 0
    $mem = $_.Memory
    $disks = $_.Disks
    
    $info = [PSCustomObject] @{
        Name        = $_.VM.Name
        IP          = $_.IP
        PRD         = $_.PRDCode
        VLAN        = $_.VLAN
        Cluster     = $_.Cluster
        State       = $_.State
        CPUCount    = $_.VM.ProcessorCount
        MemoryDyn   = $mem.DynamicMemoryEnabled
        MemoryStart = ($mem.Startup/1GB)
        MemoryMin   = ($mem.Minimum/1GB)
        MemoryMax   = ($mem.Maximum/1GB)
        MemoryBuff  = $mem.Buffer
        StopAct     = $_.StopAct
    }

    if ($showDisk){
        $disks | ForEach-Object {
            Add-Member -InputObject $info -NotePropertyName ("DiskName_{0}" -f $diskCount) -NotePropertyValue ((Split-Path $_.Path -Leaf) -split '-')[5]
            Add-Member -InputObject $info -NotePropertyName ("DiskSize_{0} (Gb)" -f $diskCount) -NotePropertyValue ($_.Size/1GB)
            Add-Member -InputObject $info -NotePropertyName ("DiskFile_{0}" -f $diskCount) -NotePropertyValue ([Math]::Round($_.FileSize/1GB))
            Add-Member -InputObject $info -NotePropertyName ("DiskType_{0}" -f $diskCount) -NotePropertyValue $_.VhdType
            $diskCount ++
        }
    }
    
    $info

} | Sort-Object Name | FT -Property * 

No comments:

Post a Comment