Following up on one of my ‘to do’ list items, here’s what I came up with. First off, the requirement was to provide a sample of how to use PowerShell to roll back a GPO within Quest’s GPM to a previous version. Now, GPM doesn’t have a set of cmdlets (that’s coming in another post) but it does have an API, so coding this is definitely possible.
The interesting thing about a ‘rollback’ as that you don’t actually want to roll anything back. You want to restore old settings/code but you want to ‘roll foward’ since want to preserve the history of what has been deployed before. That’s what this script shows – enjoy. Oh, and the first line references a script that is available here: http://gpm.inside.quest.com/entry.jspa?categoryID=153&externalID=1870
———————————-
& 'C:Program FilesQuest SoftwareQuest Group Policy ManagerQGPMInit.ps1' -computerName questdc1
# define the GPO name, which is what people will probably know it as – this
# can be an argument to a script later
$gpoName = "VAS Policy";
$foundGPO = $false ;
# loop through all the objects in the data set and find the policy we want
foreach($currentGPO in $VCManager.GetControlledObjects("GPO") |
Where-Object {$_.Name -eq $gpoName})
{
$foundGPO = $true;
# count the number of deployed versions
$counter1 = 0;
$rollbackSuccess = $false;
# check out the GPO so we can edit it
# you can discard the contents returned since we want a previous version
$VCManager.CheckOut($currentGPO.VCId, "Rollback to previous version");
# now start rolling through history - note: the array brought back by getHistory is unsorted
# so we need to sort it, and find the 'Deploy' version that is 1 back
foreach ($action in $VCManager.GetHistory($currentGPO.VCId) | Sort-Object -Descending Version)
{
# pull back only deployed objects, since we need to go 1 back
# this should probably be deployed or registered GPOs -
# someone else can put in the additional check
if ($action.Type -eq "Deploy")
{
$counter1 += 1;
# 2 is really 2 deployed versions ago - change the 2 to
# deploy older version - make it an argument if you want flexibility
if ($counter1 -eq 2)
{
# Retrieve a backup from version control. We need this to pass
# to the GPO-specific version of the Save() method.
$rollbackVersionBackup = $VCManager.GetBackup( $currentGPO.VCId, $action.BackupId);
# This version of the Save() method is for GPOs only, and takes
# the version control ID of the GPO, a backup object, and a
# migration table. Since we're just rolling back a GPO, the
# backup is obviously from the same domain as the GPO, and we
# can just pass $null.
$VCManager.Save( $currentGPO.VCId, $rollbackVersionBackup, $null );
$VCManager.CheckIn($currentGPO.VCId, "Rolling back");
$VCManager.RequestApproval($currentGPO.VCId, "Requesting Roll back");
$VCManager.Approve($currentGPO.VCId, "Approving Roll back");
$VCManager.Deploy($currentGPO.VCId, "Deploying Roll back");
# I should probably break out of the loop here since I’m done with everything
# and there may be more versions that I will just cycle through
$rollbackSuccess = $true;
}
}
}
if( $rollbackSuccess -eq $false )
{
$VCManager.UndoCheckOut($currentGPO.VCId, "Rollback to previous version")
}
}