How to Patch Hyper-V virtual machines through PowerShell Direct

In my post introducing PowerShell Direct I showed how you could use PowerShell Direct to create, and use, a PowerShell remoting session over the VM bus instead of using WSMAN.

So, what else can you do with PowerShell Direct?

In truth, just about anything you need to but one thing that comes to mind is patching virtual machines. I expect that for the majority of your machines you’ll be using a patching mechanism such as WSUS, SCCM or a third-party product. This is great when you have full connectivity and your VMs can talk directly to your patching server. But what about non-domain machines or those VMs tucked away in their own little corner of the network that can’t communicate with your patching server. Or even those machines that need a set of patches applying before you can allow them on the network.

You can use PowerShell Direct in two ways to help resolve some of these patching issues.

Copy patch and install

The first way is to copy the required patch files to the new system and install them directly. First step is to download the patch, or patches, you need to apply – don’t forget to unlock them. Then you can create a remoting session to the virtual machine:

PS> $computer = 'W16ND01'
PS> $cred = Get-Credential -Credential "$computer\Administrator"
PS> $s = New-PSSession -VMName $computer -Credential $cred
PS> $s

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  2 Session2        W16ND01         VirtualMachine  Opened                                 Available

Copy patch

You can then copy the patch to the virtual machine

PS> Copy-Item -Path C:\Source\windows10.0-kb4013418-x64_b7165b95be791aeb025135efe60e00db2800c5c6.msu -Destination C:\Source\ -ToSession $s

You can check that the file is present on the remote machine

PS> Invoke-Command -Session $s -ScriptBlock {Test-Path -Path C:\Source\windows10.0-kb4013418-x64_b7165b95be791aeb025135efe60e00db2800c5c6.msu}
True

Install patch

And now it’s time to apply the patch:

PS> Enter-PSSession -Session $s
[W16ND01]: PS C:\Users\Administrator\Documents> wusa.exe C:\Source\windows10.0-kb4013418-x64_b7165b95be791aeb025135efe60e00db2800c5c6.msu /quiet
[W16ND01]: PS C:\Users\Administrator\Documents> get-hotfix

Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
W16ND01       Update           KB3192137     NT AUTHORITY\SYSTEM  12/09/2016 00:00:00
W16ND01       Update           KB3199986     W16ND01\Administr... 31/03/2017 00:00:00
W16ND01       Update           KB4013418     W16ND01\Administr... 12/05/2017 00:00:00
W16ND01       Update           KB3213522     NT AUTHORITY\SYSTEM  31/03/2017 00:00:00

[W16ND01]: PS C:\Users\Administrator\Documents> Exit-PSSession
PS>

The easiest way is to enter the remoting session you’ve created to the remote machine – note how the prompt changes.  Use wusa.exe to install the patch. The /quiet switch ensures that there’s no prompts for user interaction.  You can test if the patch was installed by using Get-Hotfix. The new patch will show in the list if it installed correctly.  Leave the interactive session by typing Exit-PSSession.

Using Windows Update or WSUS

Ideally you want to be downloading patches directly to the machine and installing them. Windows Server 2016 and Windows 10 supply CIM classes that enable you to download and install patches from Microsoft’s update site or a WSUS server if you’ve configured the machine to use WSUS.

Discover available patches

First, create a script block that creates an instance of a MSFT_WUOperationsSession  class. You then pipe that into Invoke-CimMethod using the ScanForUpdates method with arguments to scan for updates that aren’t installed.

PS> $sb = {
$avup = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession |
Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=0";OnlineScan=$true}
$avup.Updates
}

Use Invoke-Command to run the scriptblock against the remoting session.

PS> Invoke-Command -Session $s -ScriptBlock $sb

PSComputerName : W16ND01
RunspaceId     : 62001f7d-ae58-4cee-9f6e-a638e34d16d3
Description    : After the download, this tool runs one time to check your computer for infection by specific, prevalent malicious software (including Blaster, Sasser, and Mydoom) and helps remove any infection that is found. If an infection is found, the tool will display a status report the next time that you start your computer. A new version of the tool will be offered every month. If you want to manually run the tool on your computer, you can download a copy from the Microsoft Download Center, or you can run an online version from microsoft.com. This tool is not a replacement for an antivirus product. To help protect your computer, you should use an antivirus product.
KBArticleID    :
MsrcSeverity   :
RevisionNumber : 202
Title          : Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016  x64 Edition - May 2017 (KB890830)
UpdateID       : f989a181-f72a-4cff-b3d9-f3a4412edaa0

PSComputerName : W16ND01
RunspaceId     : 62001f7d-ae58-4cee-9f6e-a638e34d16d3
Description    : A security issue has been identified in a Microsoft software product that could affect your system. You can help protect your system by installing this update from Microsoft. For a complete listing of  the issues that are included in this update, see the associated Microsoft Knowledge Base article. After you install this update, you may have to restart your system.
KBArticleID    :
MsrcSeverity   : Moderate
RevisionNumber : 202
Title          : 2017-05 Cumulative Update for Windows Server 2016 for x64-based Systems (KB4019472)
UpdateID       : 95ff788a-8fe4-4584-bfca-7051b92405b2

In this case two updates are required.

Install patches

Installing them is a similar action to discovery. Create the script block that will use the MSFT_WUOperationsSession class but this time call the ApplyApplicableUpdates method. In this case we’re applying all available updates.

$sb = {
New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession |
Invoke-CimMethod -MethodName ApplyApplicableUpdates
}

You can then use the scriptblock in your remoting session

PS> Invoke-Command -Session $s -ScriptBlock $sb

HResult        : 0
ReturnValue    : 0
PSComputerName : W16ND01
RunspaceId     : 62001f7d-ae58-4cee-9f6e-a638e34d16d3

A return value of 0 indicates success. Anything else means something has failed.

View installed updates

You can view the installed updates

$sb = {
$inup = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession |
Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=1";OnlineScan=$true}
$inup.Updates
}
PS> Invoke-Command -Session $s -ScriptBlock $sb

When we retrieved the list of available updates the description for KB4019472 stated that an update may be required.  You can test by examining the installed updates

PS> Invoke-Command -Session $s -ScriptBlock {Get-HotFix}

Source        Description      HotFixID      InstalledBy          InstalledOn               PSComputerName
------        -----------      --------      -----------          -----------               --------------
W16ND01       Update           KB3192137     NT AUTHORITY\SYSTEM  12/09/2016 00:00:00       W16ND01
W16ND01       Update           KB3199986     W16ND01\Administr... 31/03/2017 00:00:00       W16ND01
W16ND01       Update           KB4013418     W16ND01\Administr... 12/05/2017 00:00:00       W16ND01
W16ND01       Security Update  KB4019472                                                    W16ND01
W16ND01       Update           KB3213522     NT AUTHORITY\SYSTEM  31/03/2017 00:00:00       W16ND01

Notice that KB4019472 doesn’t show any data for InstalledBy on InstalledOn – this means a reboot is required.

PS> Invoke-Command -Session $s -ScriptBlock {Restart-Computer -Force}

When the machine has finished rebooting you’ll need to re-create the remoting session – it breaks on a reboot. You can then view the installed updates

PS> Invoke-Command -Session $s -ScriptBlock {Get-HotFix}

Source        Description      HotFixID      InstalledBy          InstalledOn               PSComputerName
------        -----------      --------      -----------          -----------               --------------
W16ND01       Update           KB3192137     NT AUTHORITY\SYSTEM  12/09/2016 00:00:00       W16ND01
W16ND01       Update           KB3199986     W16ND01\Administr... 31/03/2017 00:00:00       W16ND01
W16ND01       Update           KB4013418     W16ND01\Administr... 12/05/2017 00:00:00       W16ND01
W16ND01       Security Update  KB4019472     NT AUTHORITY\SYSTEM  14/05/2017 00:00:00       W16ND01

Now KB4019472 shows who installed it and when. You’ll also notice that KB3213522 has dropped off the list – it’s been superseded by the update you installed.

This technique works for Windows Server 2016 and Windows 10. Unfortunately, there isn’t a comparable technique for earlier versions of Windows Server. There is a COM object you can use to manage updates but it won’t work through a remoting session – you have to logon onto the machine and run the code locally.

PowerShell Direct reminder

There are a few rules you need to remember when you’re using PowerShell Direct:

  • Host is Windows 10 or Server 2016 running Hyper-V
  • Guest is Windows 10 or Server 2016
  • Guest must be on the host – no cross-host access
  • Guest must be running
  • Must log onto host as Hyper-V admin
  • Must supply valid credentials for LOCAL account on guest VM.

At present, you can’t connect to a Linux virtual machine using PowerShell Direct but I fully expect this functionality to arrive in the future given PowerShell 6.0 will be available for many Linux distributions.

 

Altaro Hyper-V Backup
Share this post

Not a DOJO Member yet?

Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!

2 thoughts on "How to Patch Hyper-V virtual machines through PowerShell Direct"

Leave a comment or ask a question

Your email address will not be published. Required fields are marked *

Your email address will not be published. Required fields are marked *

Notify me of follow-up replies via email

Yes, I would like to receive new blog posts by email

What is the color of grass?

Please note: If you’re not already a member on the Dojo Forums you will create a new account and receive an activation email.