SCCM Auto Snapshot a VM before Patching Task Sequence – PowerCLI

A while ago I mentioned in a post about creating a bespoke patching task sequence for a client who wanted to snap shot every VM before patching. To do this I created a silent install wrapper for PowerCLI using PowerShell.

Anyway, as per the request… here is the script I used to snapshot a VM before patching it during the Task sequence. It must be run as a command line step and using an account that has access to VSphere.
 

########################################################################################################################
#Author:       SCCMOG - Richie Schuster - SCCMOG.COM                                                                   #
#Date:         05/01/2017                                                                                              #
#Name:         Auto Snapshot VM before Patching                                                                        #
#RunAs CMD:    Powershell.exe -Executionpolicy Bypass -File PrePatchSnapShot.ps1                                       #
#Description:  This script has been created to auto snapshot a VM before patching by a task sequence from SCCM.        #
#              The script must be run as a Command Line in the task sequence by an account with access to VSphere.     #
########################################################################################################################

#Variables
$VMname = "$env:COMPUTERNAME.YOURDOMAIN.COM"
$VIserver = "YOURVISERVER.YOURDOMAIN.COM"
#$Username = "YourDomain\admin-SCCMOG"
#$Password = "CrazyPass"

#Create Credential to pass securely
#$Cred = New-Object System.Management.Automation.PSCredential($Username, (ConvertTo-SecureString $Password -AsPlainText -Force))

#Add the VMware snapin if not added
If ((Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null ) {
    Add-PSSnapin VMware.VimAutomation.Core
    }

#Connect to VIC001
If ($global:DefaultVIServer -eq $null ) {
    Connect-VIServer -Server $VIserver #-Credential $Cred -Verbose
    }
ElseIF ($global:DefaultVIServer -ne $VIserver ) {
    #Disconnect all server connections
    Disconnect-VIServer -Server $global:DefaultVIServers -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null
    #Re-connect to specific server
    Connect-VIServer -Server $VIserver
    }

#Reset Connected Variable
$Connected = $global:DefaultVIServer.Name -eq $VIserver

If ($Connected -eq $true) {

    #Snapshot Time
    #Time Date for Snapshot name
    $Date = Get-Date
    $DateShort = $Date.ToShortDateString() -replace '[/]'
    $TimeShort = $Date.ToShortTimeString()
    $Snapshotname = "Before Patching $TimeShort $DateShort"

    #Take Snapshot
    New-Snapshot -VM $VMname -Name $Snapshotname -Description "This Snapshot was taken before patching the VM from the SCCM TaskSequence. $Date" -Verbose

    #Check Snapshot complete
    $SnapShots = Get-Snapshot -VM $VMname
    $Taken = $Snapshots.Name.Contains($Snapshotname)
    
    #If found Disconnect and Exit Script Success 0
    If ($Taken -eq $true) {
        Disconnect-VIServer -Server $VIserver -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null
        Exit 0
        }
    #If Failed Exit Script 999 Failing the Tasksequence
    Else {
    Exit 999
    }
}

Elseif ($Connected -eq $false) {
    Exit 911
    }
Else {
    Exit 912
    }
    
###################################################################################################################### 

8 Replies to “SCCM Auto Snapshot a VM before Patching Task Sequence – PowerCLI”

  1. Do you have to manually fill in the name in the script of the vm? if so how do you deploy it to let’s say hundreds of machines? you don’t have a separate package for each machine?

  2. Hi SCCM Guy,

    No, at the top of the script is the Vairables location:
    #Variables
    $VMname = “$env:COMPUTERNAME.YOURDOMAIN.COM”
    $VIserver = “YOURVISERVER.YOURDOMAIN.COM”

    The name of the machine is taken with the PowerShell environment variable and the domain is added on to get the name of the VM:
    $env:COMPUTERNAME.yourdomain.com

    That would mean that the name of the VM in VSphere would be SCCM01.YOURDOMAIN.COM
    If your naming scheme is just the computer name is the same as the VM name then change that line to just use the $env:computername.

    Hope that helps.

    Cheers,
    SCCMOG

  3. The task sequence gets deployed out to a device collection which has the VM’s or to the VIServer ? also

    #Variables
    $VMname = “$env:COMPUTERNAME.YOURDOMAIN.COM”
    $VIserver = “YOURVISERVER.YOURDOMAIN.COM”

    1. Evening 🙂

      Out to a device collection with the VM’s you are wanting to patch as members.
      Nothing should be deployed to the VIServer using this script.
      The $VIServer variable is the server you connect to during the task sequence to snap shot the VM the task sequence is running on.

      What is the naming scheme of you VMs in vSphere? do they match the Computername of the VM?

      Hope that helps, I love questions so ask away matey!

      Cheers,
      SCCMOG

  4. We have quite a few vcenters/viservers in my company, do you know if there’s a way to get the script to automatically detect which vcenter the machine is connected to and connect to the appropriate one?

    1. I believe during the script I connect to a specific viserver.
      Do the VMs have different default gateways per viserver?
      You could add an If statement to select viserver based on default gateway if that is the case.
      You need to find something that is unique.

      Hope that helps,
      SCCMOG

  5. I am able to get this to work on the client server directly, but whenever I set this a task sequence in SCCM it fails with error code 0x80070002

    This is from the smsts.log file:

Leave a Reply

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

Copyright 2016 SCCMOG | All Rights Reserved

css.php