System Center 2012 R2 Configuration Manager does a great job of deploying Windows operating systems. We (1E) have been able to hit some pretty high success rates in helping our customers with their Windows migrations. However, if not done correctly, OSD can be very dangerous and can cripple your environment in a short amount of time. Take Emory University for an example – a simple mistake was made and a Windows deployment was sent out to all laptops, desktops and servers! With the correct precautions in place, this risk can be easily minimized or even eliminated.
There are several checks and balances that can be put into place in order to prevent something like this from happening and in this post I will focus on Maintenance Windows and limiting Collections. If you are still stuck in the habit of setting up deployments to All Systems, then the best thing you can do is break that bad habit now! Otherwise, be sure to keep a copy of your resume updated in case something really bad happens.
The first thing that should be done is to create two root level collections – one for All Workstations and one for All Servers. Both of these will be limited to the All Systems collection. Also, you should limit the number of collections that are limited to the All Systems collection for performance reasons, but this goes beyond the intent of this blog post. If possible, all other collections should be limited to either the All Workstations or All Servers. By limiting an OS Deployment collection to just the All Workstations, you automatically eliminate the possibility of servers being accidentally targeted (as what happened with Emory University). Both of these collections only need to be updated once a week and can be enabled for incremental updates. Each collection will have a query based membership rule that is configured for the System Resource > Operating System Name and Version property.
The last (and most important) thing that needs to be done is an OSD Maintenance Window needs to be configured on each collection. The key is to make this window in the past. Please keep in mind that this method is not fool proof, as I will explain below. Just like wearing a seat belt in a car – it doesn’t prevent you from getting in an accident, but it will minimize the chances of getting hurt. So, the intention is to minimize the risk, just like we did by splitting up servers and workstations into two different collections. By creating a window in the past, you will prevent any future OS Deployments from running (provided they were configured with the defaults). Even if someone accidentally sent the Required OS Deployment to All Workstations, with a maintenance window set in the past, all clients would start returning the following status message:
Message ID: 10074
The program for deployment “AZ1476C5” failed (“AZ105DA7” – “*”). There is no maintenance window with a duration at least as large as the program’s defined maximum runtime. Consequently, the program may never run on the client.
Hopefully, someone monitoring the deployment will see a flood of these status messages and realize that hundreds, if not thousands of systems were about to be re-imaged and correct the targeting collection membership.
When configuring a Required Deployment, the Software Installation and System Restart behavior as it pertains to maintenance windows is unchecked by default. In other words, someone would have to make a decision to enabled both of these boxes, which would render the above fail-safe solution useless. In the next part, I will talk about other methods that can be combined with this one in order to further minimize the risk of a OSDisaster.
Below is a PowerShell script that will create the collections, schedules and maintenance windows that I talked about above. This uses newer cmdlets that are available starting in System Center 2012 R2 Configuration Manager. As always, test in a lab environment first!
#Create Root Collections with OSD MWs
#Author: Mike Terrill
#Your use of these example scripts or cmdlets is at your sole risk. This information is provided “as-is”, without any warranty, whether express or implied, of accuracy,
#completeness, fitness for a particular purpose, title or non-infringement. I shall not be liable for any damages you may sustain by using these examples, whether direct,
#indirect, special, incidental or consequential.
#Set the collection evaluation schedules
$AllWorkstationsSchedule = New-CMSchedule -Start "1/1/2014 12:00 AM" -DayOfWeek Saturday -RecurCount 1
$AllServersSchedule = New-CMSchedule -Start "1/1/2014 12:00 AM" -DayOfWeek Sunday -RecurCount 1
#Create the All Workstations collection
$AllWorkstations = New-CMDeviceCollection -Name "All Workstations" -LimitingCollectionName "All Systems" `
-RefreshSchedule $AllWorkstationsSchedule -RefreshType Both
#Create the All Servers collection
$AllServers = New-CMDeviceCollection -Name "All Servers" -LimitingCollectionName "All Systems" `
-RefreshSchedule $AllServersSchedule -RefreshType Both
#Create the All Workstations query membership rule
Add-CMDeviceCollectionQueryMembershipRule -CollectionName "All Workstations" -QueryExpression `
"select * from SMS_R_System where SMS_R_System.OperatingSystemNameandVersion like '%Workstation%'" -RuleName "All Workstations"
#Create the All Servers query membership rule
Add-CMDeviceCollectionQueryMembershipRule -CollectionName "All Servers" -QueryExpression `
"select * from SMS_R_System where SMS_R_System.OperatingSystemNameandVersion like '%Server%'" -RuleName "All Servers"
#Create a 5 min schedule in the past
$MWSchedule = New-CMSchedule -Start "1/1/2014 12:00 AM" -DurationInterval Minutes -DurationCount 5 -Nonrecurring
#Create a restrictive OSD MW that occured in the past
New-CMMaintenanceWindow -CollectionID $AllWorkstations.CollectionID -ApplyToTaskSequenceOnly -Name "Restrict OSD" -Schedule $MWSchedule
New-CMMaintenanceWindow -CollectionID $AllServers.CollectionID -ApplyToTaskSequenceOnly -Name "Restrict OSD" -Schedule $MWSchedule
Originally posted on https://miketerrill.net/