PowerShell Script for Automated Install of Hyper-V Integration Services in a VM running on Windows Server 2012 with Hyper-V V 3.0 Role using PowerShell Remoting

PowerShell Script for Automated Install of Hyper-V Integration Services in a VM running on Windows Server 2012 with Hyper-V V 3.0 Role using PowerShell Remoting
Hi Guys i stumbled upon Something Super Exciting i was able to do With Hyper-V V3 Installed on Windows Server 2012 server, I was fully able to automate the installation of integration services in a Virtual Machine using the New Hyper-V Powershell Cmdlets bundled with Windows Server 2012.I created an advanced function to automate installation of Integration Services on a VM.

Here are some script sceenshots which illustrate the entire script run process from start to finish 🙂 wohooo 🙂 its a cool achievement

Now if i Run the script again that is after the integration services are upgraded it gives me this output :),

Neat!!, it shows that we are running on latest version of Integration Services as Hyper-V Version 3.0

First i went through the Hyper-V Module and i was amazed to see that now we are being shipped with 164 🙂 set of New Cmdlets, plain Awesome!!, and the new cmdlets were much feature packed as compared to the CodePlex edition of Hyper-V Modules.

In The Script i’m using a new cmdlet being shipped with Hyper-V v3 which can be used to
associate an .iso image with a Virtual Machine.

Set-VMDvdDrive -VMName $vm -Path "C:WindowsSystem32vmguest.iso"

After This i extracted the DVD Drive letter for a VM using the new cmdlet Get-VMDvdDrive.

 

$DVDriveLetter = Get-VMDvdDrive -VMName $vm | select -ExpandProperty id |`
Split-Path -Leaf

I was able to get a little help from Adam in his blog for Hyper-V http://csharpening.net/?p=1052 which shows on how to extract the DVD drive letter using split-path and its parameter -Leaf.

Then i went on and extracted the Hyper-V Host Integration Service Version and The Virtual Machine Integration Service version using the below commands.

 

$HostICversion= Get-ItemProperty "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionVirtualizationGuestInstallerVersion" | select -ExpandProperty Microsoft-Hyper-V-Guest-Installer
    
$VMICversion = Invoke-Command -ScriptBlock {Get-ItemProperty "HKLM:softwaremicrosoftvirtual machineauto" | select -ExpandProperty integrationservicesversion } -ComputerName $comp -Credential $cred

Then i made a compare between them in an if-else loop, The If condition evaluated out as below and streamed the output to the pipeline with the Integration Service Version on Both the VM and Hyper-V Host.

if($HostICversion -eq $VMICversion) {

Write-Verbose "Hyper-V Host IC Version and the VM $vm IC Version are the same" -Verbose

$obj = New-Object psobject -Property @{

'HostIntegration Services Version' =  $HostICversion
'VMIntegration Services Version' =  $VMICversion
'Hyper-V Host Name' = hostname
'VirtualMachine Name'= $vm
}

Write-Output $obj

Once the script see’s that Integration Services Version is the same on both the VM and The Hyper-V Host, i used the Set-VMDVDdrive cmdlet to eject the vmguest.iso attached to the VM

 

Set-VMDvdDrive -VMName $vm -ControllerNumber 1 -ControllerLocation 0 -Path $null

In the Else Loop i used Invoke-Wmi Method to  Install the integration services on the Virtual Machine with out a restart.

Invoke-WmiMethod -ComputerName $comp -Class Win32_Process -Name Create -ArgumentList "$($DVDriveLetter):supportx86setup.exe /quiet /norestart" -Credential $cred

Once the wmi command got completed i put a while loop in the script to check if the setup service got started and waited for it to finish, which implicates wait for the integration service to get installed.

start-sleep 3          

while (@(Get-Process setup -computername $comp   -ErrorAction SilentlyContinue).Count -ne 0) {
Start-Sleep 3
Write-verbose "Waiting for Integration Service Install to Finish on $comp ..." -Verbose
    }

write-verbose  "Completed the Installation of Integration Services" -Verbose
write-verbose  "Restarting Computer for Changes to Take Place" -Verbose

Once the installation was done i invoked a Restart-Computer with a wait for WinRM service to come up :), now thats a super neat feature in New PowerShell v3 🙂

Restart-Computer -ComputerName $comp -Wait -For WinRM -Force -Credential $cred

Once the Server Got Restarted i was able to see this pretty cool output on my powershell prompt that the integration services version did get upgraded to latest as per Hyper-V 3 🙂

write-verbose “$vm Is Online Now” -Verbose

$VMICversion = Invoke-Command -ScriptBlock {Get-ItemProperty "HKLM:softwaremicrosoftvirtual machineauto" | select -ExpandProperty integrationservicesversion } -ComputerName $comp -Credential $cred
write-verbose  "$vm New Integration Services Version $VMICversion" -Verbose

Here’s the Entire Script For Your Reference 🙂

 

  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
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<#
.Synopsis
   Hi Guys Here's a powershell script i created for Automated Install of Hyper-V Integration Services in a VM 
   running on Windows Server 2012 with Hyper-V V 3.0 Role using PowerShell Remoting.

   Special Thanks to Adam with his blog http://csharpening.net/?p=1052, which gave the required inspiration to me to develop this script

   Author - Vinith Menon http://powershell-enthusiast.blogspot.in/ 

.EXAMPLE

   Install-VMIntegrationService -VMName "ev.VMWIN2K8R2-1.H" -VMComputerName "VMWIN2K8R2-1" -username powershell-enthadministrator -password A2011
#>
function Install-VMIntegrationService
{
    [CmdletBinding()]
    
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
        $VMName,

        # Param2 help description
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=1)]
        $VMComputerName,

          # Param2 help description
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=2)]
        $username,

          # Param2 help description
        [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=3)]
        $password
               
    )

    foreach ($vm in $vmname)

    {

    foreach ($comp in $VMComputerName)

    {

    $pass =  ConvertTo-SecureString  -String $password -AsPlainText -force
    $cred = New-Object System.Management.Automation.PsCredential($username,$pass)

    Set-VMDvdDrive -VMName $vm -Path "C:WindowsSystem32vmguest.iso" 

    $DVDriveLetter = Get-VMDvdDrive -VMName $vm | select -ExpandProperty id | Split-Path -Leaf

    $HostICversion= Get-ItemProperty "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionVirtualizationGuestInstallerVersion" | select -ExpandProperty Microsoft-Hyper-V-Guest-Installer
    
    $VMICversion = Invoke-Command -ScriptBlock {Get-ItemProperty "HKLM:softwaremicrosoftvirtual machineauto" | select -ExpandProperty integrationservicesversion } -ComputerName $comp -Credential $cred

    if($HostICversion -eq $VMICversion) {

    Write-Verbose "Hyper-V Host IC Version and the VM $vm IC Version are the same" -Verbose

    $obj = New-Object psobject -Property @{

    'HostIntegration Services Version' =  $HostICversion
    'VMIntegration Services Version' =  $VMICversion
    'Hyper-V Host Name' = hostname
    'VirtualMachine Name'= $vm
    }

    Write-Output $obj

    Set-VMDvdDrive -VMName $vm -ControllerNumber 1 -ControllerLocation 0 -Path $null
        
    }

    else {

    $VMICversion = Invoke-Command -ScriptBlock {Get-ItemProperty "HKLM:softwaremicrosoftvirtual machineauto" | select -ExpandProperty integrationservicesversion } -ComputerName $comp -Credential $cred
    write-verbose  "$vm Old Integration Services Version $VMICversion" -Verbose


    Invoke-WmiMethod -ComputerName $comp -Class Win32_Process -Name Create -ArgumentList "$($DVDriveLetter):supportx86setup.exe /quiet /norestart" -Credential $cred

    #$ICInstallString = "'$dvddriveletter':supportamd64setup.exe /quiet"
    #([WMICLASS]"$compROOTCIMV2:win32_process").Create($ICInstallString) | out-null 
    
    start-sleep 3          
 
    while (@(Get-Process setup -computername $comp   -ErrorAction SilentlyContinue).Count -ne 0) {
        Start-Sleep 3
        Write-verbose "Waiting for Integration Service Install to Finish on $comp ..." -Verbose
    }

    write-verbose  "Completed the Installation of Integration Services" -Verbose
    write-verbose  "Restarting Computer for Changes to Take Place" -Verbose


    #Restart-Computer -ComputerName $comp -Wait -For WinRM -Force -Protocol WSMan -Credential $cred

    Restart-Computer -ComputerName $comp -Wait -For WinRM -Force -Credential $cred
    
    
    write-verbose  "$vm Is Online Now" -Verbose
    $VMICversion = Invoke-Command -ScriptBlock {Get-ItemProperty "HKLM:softwaremicrosoftvirtual machineauto" | select -ExpandProperty integrationservicesversion } -ComputerName $comp -Credential $cred
    write-verbose  "$vm New Integration Services Version $VMICversion" -Verbose

    Set-VMDvdDrive -VMName $vm -ControllerNumber 1 -ControllerLocation 0 -Path $null
       

}
     



    }




    }

  



}
# SIG # Begin signature block
# MIID8QYJKoZIhvcNAQcCoIID4jCCA94CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU6yod37D3Nv1bNpMhH6AYLlmj
# 9uugggIQMIICDDCCAXmgAwIBAgIQhlfUKTyJ+75Jv/MCo3iQ8zAJBgUrDgMCHQUA
# MBcxFTATBgNVBAMTDFZpbml0aCBNZW5vbjAeFw0xMjEwMjMxMjQ0MDFaFw0zOTEy
# MzEyMzU5NTlaMBcxFTATBgNVBAMTDFZpbml0aCBNZW5vbjCBnzANBgkqhkiG9w0B
# AQEFAAOBjQAwgYkCgYEA1omAIG/bEKCbtgavJtjjh30PIFGzBi+HU2b16f+NqXiA
# vW7OzeiG60M36Ni7hfX8ANak6WfwV0pTiOZXxA65Gml/xU/hdDsM/2BcBRn7X836
# l53KcV3h7c0epM4kifOe5NESk63rkIPxVMjiG+4iGLa6VFbawJ+Tpg0DjlcpnLcC
# AwEAAaNhMF8wEwYDVR0lBAwwCgYIKwYBBQUHAwMwSAYDVR0BBEEwP4AQS11gR8gM
# 74mXY/Q289zhx6EZMBcxFTATBgNVBAMTDFZpbml0aCBNZW5vboIQhlfUKTyJ+75J
# v/MCo3iQ8zAJBgUrDgMCHQUAA4GBAFTg5sfSVA/ngdwToYUzgzfsBiMpTVefmPZ8
# RQuaai1MGdKGYQhllog3JiP49wNoFAogz05O6F2Y+CcaD4uWlRoDYpgmQIcvfO9L
# UTHJfOYnZOlUP9XYV3zYTX6euaNj4POnFFHvAucEMhs1b7oQDbyY7x5+MSkmskSY
# 0IfbyEuVMYIBSzCCAUcCAQEwKzAXMRUwEwYDVQQDEwxWaW5pdGggTWVub24CEIZX
# 1Ck8ifu+Sb/zAqN4kPMwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKA
# AKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFAJf5DVSGlKkFDg40G2P6dSy
# EnVBMA0GCSqGSIb3DQEBAQUABIGAveOh626KHFL8TtniDfJ2LCjbDLG+OSK+yqyc
# +V/LrFZ/MEMqgBfj7gsmQ5nh62DE9S1ISLQO88QpmLzGXjL/LZFNFCOfxaob9rrc
# vlTB/akxebYuJeyKuaKe3zOAoE5hZm9nG+zJ7V3omD3rPDkyzyeqOKWywtgPSah5
# 0xAdnN8=
# SIG # End signature block

Share this post

15 thoughts on “PowerShell Script for Automated Install of Hyper-V Integration Services in a VM running on Windows Server 2012 with Hyper-V V 3.0 Role using PowerShell Remoting

  1. Verry good script, I use a cluster and I had to change:

    Set-VMDvdDrive -VMName $vm -Path "C:WindowsSystem32vmguest.iso"

    to:

    Set-VMDvdDrive -VMName $vm -Path "C:WindowsSystem32vmguest.iso" -AllowUnverifiedPaths

    But everything works great now.

    Reply
  2. I'm a powershell noob, but I tested your script in my lab with Server 2012 R2 and it worked great! Upgraded all my VM and I learned alot. Thanks for sharing!

    Reply
  3. when I run the command nothing happens? I am running from windows server 2012.. I copied the script to a folder and running the command from there..
    Install-VMIntegrationService -VMName "ev.VMWIN2K8R2-1.H" -VMComputerName "VMWIN2K8R2-1" -username

    what is ev.VMWIN2K8R2-1.H means?

    Reply
  4. Thanks for the script!
    How would you use this script if you want to use it on three hyper-v hosts, each of them running 40-50 vm´s?

    Regards,
    Tony

    Reply
  5. hi im new to power shell is there any material to automate the virtual machine creation in hyper-v using powershell along with adding the network and also the iso files also

    Reply
  6. # This script creates a new Hyper-V machine with hard drive, memory & network resources configured.

    # Variables
    $SRV1 = Read-Host "Enter the Virtual Machine name (Press [Enter] to choose Server01): "
    if ($SRV1 -eq ""){$SRV1="Server01"} ; if ($SRV1 -eq $NULL){$SRV1="Server01"}

    $SRAM = Read-Host "Enter the size of the Virtual Machine Memory (Press [Enter] to choose 512MB): "
    if ($SRAM -eq ""){$SRAM=512MB} ; if ($SRAM -eq $NULL){$SRAM=512MB}

    $SRV1VHD = Read-Host "Enter the size of the Virtual Machine Hard Drive (Press [Enter] to choose 40GB): "
    if ($SRV1VHD -eq ""){$SRV1VHD=40GB} ; if ($SRV1VHD -eq $NULL){$SRV1VHD=40GB}

    $VMLOC = Read-Host "Enter the location of the Virtual Machine file (Press [Enter] to choose C:HyperV): "
    if ($VMLOC -eq ""){$VMLOC="C:HyperV"} ; if ($VMLOC -eq $NULL){$VMLOC="C:HyperV"}

    $Network1 = Read-Host "Enter the name of the Virtual Machine Network (Press [Enter] to choose Network1): "
    if ($Network1 -eq ""){$Network1="Network1"} ; if ($Network1 -eq $NULL){$Network1="Network1"}

    $ISOPath=Read-Host "Enter the path of the Image file to add to the Virtual Machine: "

    #write the output of the user input
    write-output " "
    write-output " "
    write-output " "
    write-output " "
    write-output " "
    write-output "the user input values are as below:"
    write-output "The Virtual Machine Name is :" $SRV1
    write-output "The size of virtual machine is :" $SRAM
    write-output "The size of the Virtual Machine Hard Drive is :" $SRV1VHD
    write-output "The location of the Virtual Machine file is:" $VMLOC
    write-output "The Virtual Machine Network is:" $Network1
    write-output "The Virtual Machine ISOPath is:" $ISOPath

    # Configure Hyper-V Virtual Network
    remove-vmswitch $Network1 -force -erroractionsilentlycontinue
    new-vmprivateswitch $Network1

    # Create Virtual Machines
    MD $VMLoc -erroractionsilentlycontinue
    new-vm $SRV1 -path $VMLoc
    new-vhd -vhdpaths $VMLoc$SRV1 -size $SRV1VHD
    add-vmdisk -vm $SRV1 -controllerid 0 -lun 0 -path $VMLoc$SRV1
    get-vm $SRV1 | add-vmdrive -controllerid 1 -lun 0 -dvd
    get-vm $SRV1 | set-vmmemory -memory $SRAM
    get-vm $SRV1 | add-vmnic -virtualswitch $Network1
    Add-VMDvdDrive -VMName $SRV1 –Path $ISOPath

    Will the above code work

    Reply

Post Comment