Configuration Manager PowerShell - Changing Package Source Location
Today we are going to examine 2 PowerShell CMDLETS that are new to Configuration Manager 2012 SP1.
Get-CMPackage
Set-CMPackage
As you might have guessed, these two cmdlets allow us to view and modify attributes related to our packages. These two commands can be extremely useful and powerful. Let's take a look at this scenario.
You are the Configuration Manager administrator and are working on migrating your packages from CM 2007 to CM 2012. As you already discovered, your packages must be using the UNC path for their source files instead of the "local drive on site server". To support this, you created a share on your CM 2007 Primary Site (Lets call is \\CM07\PKGSRC).
You have migrated your packages using the CM 2012 Migration Wizard, but their Source path is still located on \\CM07\PKGSRC. You want to shut down the old server, but to do that, you need to move all the source files. You have already copied all the data to \\SOURCESVR\PKGSRC but now you need to change all of your packages to the new UNC path.
If you have a limited number of package, this might not be a problem, but if you have hundreds or thousands of packages, this could be a lot of work. How can we automate or simplify this process? PowerShell!
First, you need to launch the Configuration Manger PowerShell provider,
Now with the PowerShell console open, let's run a command that will output all of our packages and the attributes we need to change to a CSV file by executing the following command:
Get-CMPackage | select Name, PackageID, PkgSourcePath | export-csv $home\documents\packages.csv
Let's break down this command line:
Get-CMPackage: This is the Configuration Manager cmdlet that allows us to view details of a package. Executing this command on its own returns a list of all packages and all of their properties.
| : This is a BAR character that is used to pass data along the command line. In this case, we are feeding the select statement in the next step
Select Name, PackageID, PkgSourcePath: Using the select cmdlet (alias for Select-Object) allows us to only query the properties that we need for this particular activity.
|: this is a BAR character that is used to pass data along the command line. In this case, we are feeding the results of our query to create a CSV file in the next step
Export-CSV: This is a built in cmdlet that allows us to take our data export is to a CSV file
Now we can either open the CSV file with notepad or whatever CSV editor of your choice to view and change the contents. This is what mine looks like.
You can see we have the Package Name, ID, and Source Path. Using Find and Replace, I am going to change \\CM07\PKGSRC to
\\SOURCESVR\PKGSRC.
I am also going to remove the data for the package I wish to not change.
I can now import this these change back into Configuration Manager to update the package using the Set-CMPackage cmdlet.
Import-CSV C:\Users\administrator.corp\Documents\packages.csv | %{Set-CMPackage -id $_.PackageID -Path $_.PkgSourcePath}
Let's break down this command line:
Import-CSV: This cmdlet is used to read the contents of a CSV file. In this case, our modified Packages export. Executed stand alone with a CSV file parameter, it will print the results of the CSV file on the screen.
|: this is a BAR character that is used to pass data along the command line. In this case, we are feeding the CSV file into the next step
%{}: This command is shorthand for the ForEach-Object cmdlet. It allowed us to execute whatever is in the Curly Brackets {} for each line from the input, in this case are CSV File.
Set-CMPackage -id $_.PackageID -Path $_.PkgSourcePath: There is a lot going on in this line. The Set-CMPackage cmdlet is the Configuraiton Manager cmdlet that allows us to modify packages.
In order to modify the package, a unique identifier must be provided. In this case with use the -id to provide the cmdlet with the PacakgeID we want to update. Since we are using a ForEach loop, the _.PackageID command provide the data from the current line of the CSV file and the column we are referencing. In this case, PackageID.
What we want to set, if the new Package Source location that we updated in the CSV file. To do this, we need to pass the cmdlet the -Path parameter and we want the current line from the CSV file from column PKGSourcePath, thus we use $_.PKGSourcePath.
Now that you have executed the command, you can see the new source folder path updated in the console on the package
These procedures and cmdlets are provided as sample guidance only. I highly recommend you test them before use in your production environments
This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute the object code form of the Sample Code, provided that You agree: (i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; (ii) to include a valid copyright notice on Your software product in which the Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise or result from the use or distribution of the Sample Code.
Comments
Anonymous
January 01, 2003
Great info! Wondering about the syntax of the Import command if we want to import more than one field. We're doing cleanup from our 2007 -> 2012 migration, and want to standardize several fields in the same Package. Or are we limited to Importing one field at a time? Thanks!Anonymous
April 18, 2013
The comment has been removedAnonymous
November 09, 2013
Hi, I tried the first Powershell command you wrote and I received only the Package ID from all packages. the problem was not keeping on uppercaseLowercase letters of the object names. the command should be like this: Get-CMPackage | select Name, PackageID, PkgSourcePath | export-csv $homedocumentspackages.csv but many thanks, it works great now! :)Anonymous
November 21, 2013
Thanks Ori. I know that it worked previously so during one of the updates, the cmdlets must have become Case Sensitive. I'll update the syntax.Anonymous
February 12, 2014
Hello Everyone! This is a follow up to a blog I posted previously, Changing Package Source Location