Migrate a Custom Application using USMT

Recently, I received request from a regional administrator to migrate the settings of an in-house application when USMT ran. Since the settings were not part of the migration, he had to manually configure them each time. To do this, I created a custom xml file that is called when Scanstate and Loadstate run. Now, the settings are migrated and no manual configuration is required.

Microsoft has an excellent article on how to perform this. Below are the steps that I used along with some key information from Microsoft.

Steps

Note - The application that I migrated only had one version. Additional versions should be exained for changes in the settings to migrate.

  1. Confirmed all settings to migrate with the application owner. 
  2. Created a virtual machine and installed Windows 7 on it. (Ensured no additional applications were installed.)
  3. Started Filemon and Regmon. 
  4. Installed the application and monitored the installation for any registry or file changes using Filemon and Regmon.
  5. Checked the uninstall key in the registry and ensured that it was correct. (Used for detecting if the application is installed.)
  6. Created a new custom.xml file that contain the settings to migrate based on the information gathered during the monitoring in step 4.
  7. Tested the new migration settings by running Scanstate on an existing machine with the application installed (settings configured) and running Loadstate with the application installed (settings no configured).
  8. Confirmed that settings migrated properly and application performs properly.

PowerShell 3.0 - Create and Configure Multiple Hyper-V 2012 VMs

 From time to time, I like to rebuild my lab environment from scratch. In the past, I created each virtual machine manually and configured it. To speed this process up, I created a PowerShell script that uses the native Hyper-V 3.0 module in Windows Server 2012. Now, I simply run my script to create and configure my servers. Below are the steps I perform to run my script. I am working on a version 2 of the script with additional automation, error handling and logging. 

Note - My lab environment is Hyper-V 3.0 on Windows Server 2012 on a single server. 

  1. Created a file called servers.txt in c:\temp containing the names of the servers I wanted to create.
  2. If needed, I adjusted the baseline memory, baseline drive size and location of the Windows Server 2012 ISO in the script.
  3. Ran script and confirmed servers were created with the right settings. 

SCCM 2012 - Group Software Updates for Easier Deployment

During some testing I was doing in my lab, I noticed several security updates that were listed as Required. To get a full view of what was missing, I used grouping, and I was able to quickly determine what updates were required but not deployed to my test machines. Below are the steps I performed to display all updates with a Required status.

  1. Clicked Software Updates.
  2. Right-Clicked Title and scrolled to the bottom of the menu.
  3. Selected Group By and chose Required.
  4. Software Updates are now grouped by Required status and show the number of machines missing the update.

SCCM - Create Custom Status Message Query

Recently, I was experiencing software distribution problems on one of my SCCM servers.  I examined the status messages for the Distribution Manager components numerous times throughout the day while I tried to pinpoint the problem. By default the SCCM console has a status message query that displays the status message for a specific component during a specific time period. This query works well but has three prompted values. To speed up the troubleshooting process, I created a custom status message query that automatically contained what site and component I wanted to view the status messages for. Now, I can run my custom query and only have to supply the time period I want the messages displayed for. Below are the steps I took to create the custom query.

Steps:

  1. Right-click Status Message Queries and click Create Status Message Query.
  2. Name the Query and click Import Query Statement.
  3. Select the All Status Message from a Specific Component at a Specific Site.
  4. Click the Criteria tab and change the Component criterion properties to a Simple Value type with a value of SMS_DISTRIBUTION_MANAGER.
  5. Change the Site Code criterion properties to a Simple Value type with the Site Code value of my problem server.
  6. Click OK and close wizard.

SCCM 2012 - Error when trying to edit task sequence

Recently, I was editing a task sequence on my SCCM 2012 lab primary server when the VM crashed. I was able to fix it but when I tried to edit my task sequence again I received an error message that the task sequence was not available for editing because it was in use. I did some digging and found a table in the SCCM database called SEDO_LockState. SCCM uses it to prevent objects in the SCCM admin console such as task sequences, software update deployment packages, etc. from being edited if they are already open by someone else. Examining the table, I could see that a LockedStateID of 1 meant that the object was locked and 0 meant that is was not. I created the below query to output what was locked under my Lab\admin1 account.

SELECT *

FROM SEDO_LockState

WHERE AssignedUser = 'LAB\admin1' AND LockStateID = 1

Using this information, I ran the below to delete the lock. After deleting, I could edit my task sequence again.

Note:  Editing the SCCM database is not supported by Microsoft. This was done in a test lab. Microsoft support should be contacted if this problem occurs in a production environment.

DELETE FROM SEDO_LockState WHERE AssignedUser = 'Lab\admin1' AND LockStateID = 1

PowerShell - Copy Logs during SCCM OS Deployment

In an earlier post, I outlined the steps I used to automate my testing procedure during SCCM OSD testing. One of the steps I like to perform is copying the SCCM logs and unattend.xml to share on my SCCM server for examination. To do this, I created a PowerShell script that, combined with the MDT Gather step, copies the correct files to my desired location. This has sped up my image deployment testing.

Using Custom Properties in the CustomSettings.ini during SCCM OS Deployments

When I test a new image, script, task sequence, or task sequence step in an image deployment, I find it useful to pause the build and/or copy logs at certain points during the process . In the past, I would bring up the command prompt and perform the steps manually. I found this method slowed down the test process. Rather than continuing to perform the steps manually, I decided to automate the process. Below are the steps I performed.

Steps

Note - My CustomSettings.ini file is already configured to query against the ComputerSettings table in the MDT database using the MAC address of the machine I am building. This table contains all the settings to be configured for each one of my test machines.

  1. Created a new PowerShell script to copy the desired SCCM logs and files that I wanted to examine during testing.
  2. Added the CopyLogs and my existing Pause PowerShell script to the script folder in my MDT Toolkit package. 
  3. Added four new columns to the ComputerSettings table in my MDT database. I called the columns Troubleshoot, EnterpriseLocation, Pause, and CopyLogs.
  4. Using the Deployment Workbench, I updated the value of the three settings to Yes for a machine I was using to test Windows 8 deployments for Troubleshoot, Pause, and CopyLogs.
  5. For EnterpriseLocation, I updated its value to the location I wanted the logs copied to.
  6. Added the four custom properties to my CustomSettings.ini file in my Custom Settings build package and updated the package on the DPs.
  7. Added a new group called Troubleshoot to my Windows 8 deployment task sequence.
  8. Added two new steps to the Troubleshoot group with one step configured to run the Pause script and the other configured to run the CopyLogs script.
  9. Added a condition to the Troubleshoot group to run only if the Troubleshoot task sequence variable was set to Yes.
  10. Added a condition to the Pause step to run only if the Pause task sequence variable was set to Yes.
  11. Added a condition to the CopyLogs step to run only if the CopyLogs task sequence step was set to Yes.

With the new configurations completed, the logs are automatically copied to the location I configured and the build pauses at the time I desire. To stop the steps from running, I use the Deployment Workbench to simply remove the Yes value from the machine.

SCCM 2012 Build Fails with 0x80070002 after updating package

Recently, I was doing some Windows 8 deployment testing. Part of my testing involved running a new stored procedure to gather information for a troubleshooting step that I am developing. Rather than modify my existing CustomSettings.ini to call the stored procedure, I created a new .ini file called Troubleshooting.ini. I added it to my Custom Settings package and updated the distribution points. I decided to test it on a machine that had previously failed to install Windows 8. I started the build on the machine and began working on another problem. When I returned, I noticed that the build had failed with 0x80070002. It was stuck at downloading the Troubleshooting.ini. I took a look at smsts.log and discovered the problem. Since the "Partition if necessary" step was skipped, the files used during the previous failed build remained. SCCM tried to download the custom settings files but could not because it could not overwrite the existing files and experience the failure. Since this was a rare problem, I decided not to adjust the "Partition if necessary" step. Instead, I used diskpart to clean the disk. Once cleaned, the machine was able to build successfully and allowed me to continue testing.

SQL Query to report machine information for users in two separate SCCM user collections

Recently, management asked me to gather machine information for several hundred users in two different SCCM user collections. There were several requirements for the report: All information must be in one report and users without a machine should be listed as so in the report. To meet the "users without machine" requirement, I used a Left Outer Join to display all users in the collection. Any user that was in the collection but whose user name was not in the System view would be listed as "No" under the machine column. If the user name was in the System view, "Yes" would be listed under the Machine column. To combine the results into one report, I used Union to combine the two select statements into one. I selected Union instead of Union All to avoid duplicates.

SQL Query to find the installation status of packages referenced by an SCCM task sequence

I recently created a task sequence in my SCCM 2007 environment that referenced numerous packages. Several of the packages that were referenced were not on the DP. In SCCM 2012, it is easy to find out what packages are missing from a DP. In SCCM 2007, it is more difficult. There is a report that lists all the packages referenced by a task sequence, but no report that lists the installation status of each package referenced by a task sequence on a specific site. To quickly get the information, I created a SQL query that output the name and package ID of every package a task sequence referenced and its installation status on a specific site.

Note - Query can easily be converted to an SCCM report that asks for the site code and task sequence package ID. This would allow it to be run against any site in a hierarchy without making manual changes. 

Example - Change PSD.SiteCode = '<<SiteCode of the DP to Check>>' to PSD.SiteCode = @SiteCode and configure the report to use a prompt that ask for the site code.