7 Replies Latest reply on Jan 15, 2020 9:23 AM by LucD

    GET-WMIObject over Invoke-VMScript

    vespavbb Novice

      Hi,

      Actually I´m looking for a monster script to extend a Windows Drive by passing only the Information " VMname, Driverletter, extendbyGB

      The Script should collect all Information like the correct vmdk, check Datastoresfreespace , Extend the vmdk, Extend the correct Drive inside the VM..

       

      this is one part of the script..

       

      Remote WMI is not enalbed and I cant not do a get-wmiObject -servername remotely.

      My Idea was to do an Invoke-command to get the wmi information from inside the vm.

       

      Invoke runs, but the output is wrong DeviceID is not recognized, do I need to pass the $Drive to the remotecommand? If yes, how?

      $SystemFQFDN = "vmtest01"

      $Username = "Administrator"

      $Password = "blabla"

       

      $Drive = 'd:'

       

      $VMName = ($SystemFQFDN.Split('.'))[0]

       

      $SecureStringPwd = $Password | ConvertTo-SecureString -AsPlainText -Force

      $creds = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecureStringPwd

       

       

      Write-Host " invokeWMI $vmname" -ForegroundColor Green

       

      $invokescript = " (((Get-WmiObject -ClassName 'Win32_LogicalDisk') | WHERE {$_.DeviceID -eq $Drive}).GetRelated('Win32_DiskPartition')).GetRelated('Win32_DiskDrive') | Select * "

                         

      $Windrive = Invoke-VMScript -vm $vmname -ScriptType Powershell -ScriptText $invokescript -GuestUser $UserName -GuestPassword $pw.password

      $Windrive

        • 1. Re: GET-WMIObject over Invoke-VMScript
          LucD Guru
          User ModeratorsCommunity WarriorsvExpert

          I hate to disappoint you but there is no fool-proof method to link a VMDK to a guest OS partition.

           

          On the script, you placed it in double quotes, that means  that all variables will be substituted, including $_.DeviceID and $Drive.
          If I understand your intention correctly, that is probably not what you want for $_.DeviceId.

          One option is to escape the $-sign with a back-tick.

          A short demo snippet

           

          $var1 = 1

          $var2 = 2

          $t1 = "$var1 and $var2"

          $t1

          $t2 = "`$var1 and $var2"

          $t2

          Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
          • 2. Re: GET-WMIObject over Invoke-VMScript
            vespavbb Novice

            Hi Luc,

             

            sorry I dont unterstand for sure.

             

            but in Gerneral, how can i pass some $var´s in a scripttext over Invoke? Sometimes I see scripttext, or scriptblock

             

            I testet someting like this, but its not working.:-(

            thanks for your patience

             

            Example

            $SystemFQFDN = "vmtest01.test.local"

            $UserName = 'administrator' # Subscribe your Variable for User with access to VCenter and VM

            $pw = "mypass"

             

             

            $Drive = 'd:'

            $argsArray = @()

            $argsArray += $Drive

             

            $VMName = ($SystemFQFDN.Split('.'))[0]

             

            $SecureStringPwd = $Pw | ConvertTo-SecureString -AsPlainText -Force

            $creds = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecureStringPwd

             

            $Windrive = Invoke-VMscript -vm $vmname -ScriptType Powershell -GuestUser $UserName -GuestPassword $pw.password  -ScriptText {

            Param(

                    [string]$Drive

                )

                (((Get-WmiObject -ClassName 'Win32_LogicalDisk') | WHERE {$_.DeviceID -eq $Drive}).GetRelated('Win32_DiskPartition')).GetRelated('Win32_DiskDrive') | Select *

             

             

            $resultArray = @()

             

            return  $resultArray

             

             

            }

            $Windrive

            • 3. Re: GET-WMIObject over Invoke-VMScript
              LucD Guru
              vExpertCommunity WarriorsUser Moderators

              I use a code-block with single quotes.
              And I escape (backtick) the dollar signs I don't want to have substituted.

              Have a look at my Here string and variable substitution dive

              Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
              • 4. Re: GET-WMIObject over Invoke-VMScript
                vespavbb Novice

                ok now i found out how to invoke this. The Problem now is, that the output is a text arry and I dont know how to pic a special line like SCSIBUS,SCSITargetID,DiskSNfromWMI

                I used the "ScriptOutput funktion, I guess this is the only way to get the output nativ.

                 

                Write-Host " invokeWMI $vmname" -ForegroundColor Green

                 

                $MyScript = @"

                 

                (((Get-WmiObject -ClassName 'Win32_LogicalDisk') | WHERE {`$_.DeviceID -eq "$Drive"}).GetRelated('Win32_DiskPartition')).GetRelated('Win32_DiskDrive') | Select *

                 

                "@

                                    

                $Windrivetemp = Invoke-VMScript -vm $vmname -ScriptType Powershell -ScriptText $myScript -GuestUser $UserName -GuestPassword $pw.password

                 

                $Windrive = $windrivetemp.ScriptOutput

                $Windrive

                #$outputarray = ($Windrivetemp -split('\n'))

                 

                ###this is not working

                $SCSIBus = $Windrive.SCSIBus

                $SCSITargetId =$Windrive.SCSITargetId

                $DiskSNfromWMI = $Windrive.SerialNumber

                • 5. Re: GET-WMIObject over Invoke-VMScript
                  LucD Guru
                  vExpertUser ModeratorsCommunity Warriors

                  The ScriptOutput property of the returned object contains the output from the script that ran inside the guest OS.

                  The data in there is one string.

                   

                  One method to interpret the output on the receiving end is to use a well-known format.

                  In the following, I use the CSV format.

                  The result will be one or more objects, each with the desired properties.

                   

                  Write-Host " invokeWMI $vmname" -ForegroundColor Green

                   

                  $SecureStringPwd = $Password | ConvertTo-SecureString -AsPlainText -Force

                  $creds = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecureStringPwd


                  $MyScript = @"

                  ((Get-WmiObject -ClassName 'Win32_LogicalDisk' |

                  WHERE {`$_.DeviceID -eq "$Drive"}).GetRelated('Win32_DiskPartition')).GetRelated('Win32_DiskDrive') |

                  Select-Object -Property SCSIBus,SCSITargetId,SerialNumber |

                  ConvertTo-Csv

                  "@


                  Invoke-VMScript -vm $vmname -ScriptType Powershell -ScriptText $myScript -GuestCredential $creds |

                  Select -ExpandProperty ScriptOutput |

                  ConvertFrom-Csv -UseCulture

                  Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                  • 6. Re: GET-WMIObject over Invoke-VMScript
                    vespavbb Novice

                    ok, here is the final script

                    Extend VMDK and Windows Drive inside the VM with Parameter of VMname and Driveletter

                    In my case it was working, just the check Datastore Freespace thing is not done yet

                    what do you think?

                     

                    Param(

                        $DeineVM = (Read-Host "Select VMname"),

                        $Drive = (Read-Host "Select Drive Letter")+":"

                    )

                     

                     

                    $SystemFQFDN = $DeineVM #Subscribe the Published Data of the affected VM

                    $UserName = 'administrator' # Subscribe your Variable for User with access to VCenter and VM

                     

                    #getting the Laps pw

                    $pw = get-adcomputer $SystemFQFDN -Properties * | select @{Label="Name";Expression={$_.name}}, @{Label="OS";Expression={$_.operatingsystem}}, @{Label="Distinguished name";Expression={$_.'distinguishedname'}}, @{Label="Password";Expression={$_.'ms-Mcs-AdmPwd'}} | select Password

                     

                     

                    $Password = $pw # Subscribe your encrypted Variable for the Password

                     

                     

                    #VName equals Netbios name here

                    $VMName = ($SystemFQFDN.Split('.'))[0]

                     

                     

                    #Make Credentials

                    $SecureStringPwd = $Password | ConvertTo-SecureString -AsPlainText -Force

                    $creds = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecureStringPwd

                     

                     

                    Write-Host " invokeWMI $vmname" -ForegroundColor Green

                    #$invokescript = " ipconfig /all"

                     

                     

                    $MyScript = @"

                     

                     

                    ((Get-WmiObject -ClassName 'Win32_LogicalDisk' |

                     

                     

                    WHERE {`$_.DeviceID -eq "$Drive"}).GetRelated('Win32_DiskPartition')).GetRelated('Win32_DiskDrive') |

                     

                     

                    Select-Object -Property SCSIBus,SCSITargetId,SerialNumber |

                     

                     

                    ConvertTo-Csv

                     

                     

                    "@

                     

                     

                    $Windrive = Invoke-VMScript -vm $vmname -ScriptType Powershell -ScriptText $myScript -GuestUser $UserName -GuestPassword $pw.password |

                     

                     

                    Select -ExpandProperty ScriptOutput |

                     

                     

                    ConvertFrom-Csv -UseCulture

                     

                                        

                    $Windrive

                    #$outputarray = ($Windrive -split('\n'))

                     

                     

                    $SCSIBus = $Windrive.SCSIBus

                    $SCSITargetId =$Windrive.SCSITargetId

                    $DiskSNfromWMI = $Windrive.SerialNumber

                     

                     

                    # Match the VMWare Disk with the windows Disk

                    $vm = Get-VM -Name $VMName

                     

                     

                    foreach($ctrl in Get-ScsiController -VM $vm)

                    {

                     

                     

                    foreach($disk in (Get-HardDisk -VM $vm | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key}))

                    {

                     

                     

                    IF (($disk.ExtensionData.UnitNumber -eq $SCSITargetId )-and (($disk.ExtensionData.Backing.Uuid).Replace('-','') -eq $DiskSNfromWMI) )

                    {

                    # The below Variables are for the tab Published Data of "Run .Net Script" Activiy

                    $VMDiskName = $disk.Name

                    $VMDiskFilename = $disk.Filename

                    $DiskUID = $disk.Uid

                    $DiskCapacityGB = $disk.CapacityGB

                    $DiskFreeSpaceGB = ((Get-VMGuest -VM $vm).Disks | where {$_.Path -eq "$Drive\"}).FreeSpaceGB

                    $DiskFreeSpaceGB = "{0:N3}" -f ([math]::Round($DiskFreeSpaceGB,3))

                    }

                     

                     

                    }

                    }

                     

                     

                    $LUN = Get-HardDisk -vm $vm | Where {$_.Uid -eq $DiskUID} | Get-Datastore

                     

                     

                    $LUNName = $LUN.Name

                    $FreespaceGB = "{0:N3}" -f ([math]::Round($LUN.FreeSpaceGB,3))

                    $CapacityGB = "{0:N3}" -f ([math]::Round($LUN.CapacityGB,3))

                     

                     

                     

                    ##################

                     

                    #Driveletter will be extended with 10GB

                    $extend10GB = "10"

                    $newsize = $DiskCapacityGB + $extend10GB

                    # Extend VMDK

                    Get-HardDisk -vm $vm | Where {$_.Name -eq "$VMDiskName"} | Set-HardDisk -CapacityGB $newsize -ResizeGuestPartition -Confirm:$false

                     

                     

                    #rescan

                    Invoke-VMScript -vm $VM -ScriptText "echo select vol $drive > c:\diskpart.txt && echo rescan >> c:\diskpart.txt && diskpart.exe /s c:\diskpart.txt" -ScriptType BAT -GuestUser $UserName -GuestPassword $pw.password

                     

                     

                    #Extend Disc inside

                    Invoke-VMScript -vm $VM -ScriptText "echo select vol $drive > c:\diskpart.txt && echo extend >> c:\diskpart.txt && diskpart.exe /s c:\diskpart.txt" -ScriptType BAT -GuestUser $UserName -GuestPassword $pw.password

                    • 7. Re: GET-WMIObject over Invoke-VMScript
                      LucD Guru
                      User ModeratorsvExpertCommunity Warriors

                      Well, if it is working in your environment, so much the better.
                      Just be aware that the logic how you link the VMDK to the drive/partition might have issues when you start adding/removing harddisks to the VM and also when you start reconfiguring partitions inside the Guest OS.

                       

                      What is missing with regards to the FreeSpaceGB?

                      Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz