Deleting Orphaned Deployments
(Last updated on February 5, 2021)
This may not be the best title for this post. Deleting Orphaned Deployments may be the solution, but it is surely not the problem. The technique described here is something that you can use in other situations where an XML file is involved. The scenario that drove the writing of this post is, of course, specific to Specops Deploy.
A strange crash in the Specops Deploy Application Snap-in: An administrator will open the GPMC, find the desired GPO, open the GPO in the editor, navigate to the Specops Deploy Application snap-in, look at deployments, and suddenly the console crashes. A console crash is rare. This scenario is also rare, and it occurs if an Admin ‘deletes’ a package that is referenced in a deployment. The issue can be resolved, but it introduces a very interesting troubleshooting opportunity: How can you fix the deployment if you can’t look at it in the editor?
Specops Deploy Application stores all of the deployment information in the GPO in SYSVOL. The data is stored in an XML file called ‘Deployments.xml’. If you manually edit this file, and delete the corrupt ‘Deployment,’ you are done. This obviously is not a great move. It is ripe for errors and not a good plan of attack.
The solution here, and in reality the solution for many such problems is automation. The idea is to remove the opportunity for errors and create a process where you surgically achieve exactly what you want. Here we will call on PowerShell to help us out. One of my colleagues shared a technique to deal with XML files and it is really great. It is actually quite simple.
- Use the Get-Content cmdlet to retrieve the xml file
- Shove that file into a variable that is specifically cast as an XML file
- The document is now available as an object that can be manipulated as you need
OK, so here we go. Many assumptions are made here and keep an eye on upcoming posts to walk through additional techniques to help. This post is about the last step, cleaning up an orphaned or corrupt deployment. In my example I have a single GPO with two deployments. Imagine one of these deployments, ‘WinZip 7’, is corrupt.
I have found that this deployment has a unique ID that I will need. I can get this information through PowerShell. Ignore the cmdlets here, they are a topic for other posts. But I use the Specops Deploy Application cmdlets to get the information I need.
Specops Deploy Application – Packages
The deployment has important data that I will need, and the GPO itself has some important information as well.
Specops Deploy Application – Deployment
Specops Deploy Application – GPO
Now, I have all the information I need to find and correct my issue.
Now to the real meat of the solution. The Get-Content cmdlet will be the way we get to this information. We will throw the file into a variable that we can manipulate. Here is the command without references to my specific test environment and test GPO.
PS C:> [XML]$x = Get-Content “\dc1SYSVOL<domainName> Policies<GUID of GPO>MachineSpecopsDeployDeployments.xml”
Execute the above command then take a look at $x. It is an object ready to be used.
NOTE: Use the PowerShell ISE. The ISE provides a lot of additional capabilities that will help navigate, learn and execute on some of the tasks you are attempting. The Intellisense capability of the ISE is worth the price of admission. Once you learn how to leverage it you won’t be able to live without it.
If you type $x. on the command line you will see a list of all of the properties and methods that can be called on here.
If you choose Deployments and add ‘.’ you will see additional properties/methods.
If you play around with this technique you will begin to see how valuable this can be. For this example you want to look at $x.deployments.deployment.
For this GPO there are only the two ‘Deployments’. We only want the one for ‘WinZip 7’. This takes us back to where we found the deployment ID, Package ID etc. In this case we will only need the PackageID attribute associated with ‘WinZip 7’.
It is all coming together. At this point we have the ‘Deployments.xml’ file in the $x variable. We know the ‘Deployment ID’ is the GUID in the above image. We will create another variable to point to that specific Deployment.
This is a bit of a leap so let’s make sure we are all on the same page.
Deployments.xml file is stored in a variable, $x
The specific deployment we are targeting is stored in a variable, $s
The XML object has a method called ‘RemoveChild’that takes the GUID of the child element to delete. We pass that to the ‘RemoveChild’ method by way of the $s variable.
Then we call the ‘save’ method on $x
Done! Now if I look at Get-SDDeployment ‘WinZip 7’ is gone.
I can now open the GPO and navigate to Specops Deploy Application and my corrupt GPO is no longer a problem.
Stay tuned for more PowerShell related posts.