SCCM 2007 to 2012 migration scripts for colletions and packages.

I am still planning to write the whole great and shiny article about my operation of SCCM 2007 to 2012 migration :], but firstly I would like to publish couple of scripts that were very helpful for me.
1. The need of changing the “parent collection” for some collections came because we plan to use SCCM for managing the servers also, but we want to limit the ability of managing them to Administrators only. We do not want helpdesk admins – that are creating packages – to deploy accidentially package on any of them, or simply to have any access to them.

New SCCM has great ability – oh my God finally!!! – to restrict permissions on particular collections. So I left collection “All system” in the root “Device collections”, later I have created collection “All Workstations Helpdesk”, with limitation to “All systems” with proper query based on OU’s that is limiting it to just workstations, and put it in the folder to which I gave permissions for my helpdesk admis.

That worked great! Helpdesk Admins didn’t have any ability to change “All Workstations Helpdesk” membership, because they didn’t have permissions for (and accually didn’t even saw) “All systems” collection. And they could buil new collections based on that collection.

Old collections had to be migrated – there were advertisements that was deployed on them, my colleagues made them to make some reports for managers, or just for themselves.

The problem was, all old collections had “parent collection” set to “All systems”. Standing in front on 400 collections I made up a decision.

– Fuck, i need a script…

So here it is:

# Here I am setting up date just for logging purposes.

$date = Get-Date
$data = Get-Date –f "yyyy-MM-dd_HH";
$log_file = "c:\SCCM_Collections_Migration_$data.log"

$All_Collections = (gc c:\Collection_Name_List.txt)


Foreach ($kolekcja in $All_Collections) {
$Collection = $kolekcja
if ($Collection -eq "All Systems")

# We take the name of the current parent collection for collection that is beind processed - just in case we want to revert changes (useful :))

$Old_Collection = (Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Collection -Filter "Name='$Collection'")
$Stara_kol = $Old_Collection.LimitToCollectionName

# Here make the change of the collection, we need to know the name of the new collection AND it's ID!

$CollectionQuery = Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Collection -Filter "Name='$Collection'"
$CollectionQuery.LimitToCollectionName = "All Workstations"
$CollectionQuery.LimitToCollectionID = "WRO0000B"

#Just for logging pusposes - taking the new collection name - to be sure it has changed

$New_Collection = (Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Collection -Filter "Name='$Collection'")
$Nowa_kol = $New_Collection.LimitToCollectionName

# Here we are writing output to the file, if the names od ids are not the same - the error is being writed to the file. The error logging is maybe not so sophisticated but is enought 🙂

if (($Old_Collection.LimitToCollectionName -ne $New_Collection.LimitToCollectionName) -and ($Old_Collection.LimitToCollectionID -ne $New_Collection.LimitToCollectionID)) {
$Data_row = "Success, for collection "+$Collection+" old limiting collection "+$Stara_kol+" has been changed to "+$Nowa_kol
Add-Content $log_file "$Data_row"
} else {
$Data_row = "ERROR The problem occured when changing the parent collection!"
Add-Content $log_file "$Data_row"


The problem I met was migration of packages. Before running the migration I didn’t realize the problem, hance I was really fucking astonished when after migration the packages/advertisements I saw in distmgr.log flood of errors saying that SCCM cannot find appropriate path for sources.

I was like:


Apparently I have missed one fundamental thing – migration taks do not migrate sources and do not change the path on it.

Well… shit 🙂

I have moved the sources but I was left with almoust hundred of packages in which I had to change path to sources. Additionally I have noticed that some packages had relative path, and some not.

Here is a script for that, :

$CollectionQuery = Get-WmiObject -Namespace "root\SMS\Site_WRO" -Class SMS_Package

Foreach ($Pakiet in $CollectionQuery) {
$Sciezka = $Pakiet.PkgSourcePath
$Poprawka = $Sciezka.Replace("D:\<LOCAL_PATH.","\\<NEW_SCCM_SERVER>\E$").Replace("\\<OLD_SCCM_SERVER>\d$","\\<NEW_SCCM_SERVER>\E$")
$Pakiet.PkgSourcePath = $Poprawka

Reports migration from SCCM 2007 to SCCM 2012

Recenty I had some troubles during reports migration from SCCM 2007 to SCCM 2012.

By the way – I am going to write a quite big article about my struggling with SCCM upgrade – I hope the migration nightmare will ends this month 🙂

So as I was saying, after migrating reports I was received such an error:

The report server cannot process the report or shared dataset. The shared data source ‘AutoGen__5C6358F2_4BB6_4a1b_A16E_8D96795D8602_’ for the report server or SharePoint site is not valid. Browse to the server or site and select a shared data source. (rsInvalidDataSourceReference)

Stack Trace:
at Microsoft.Reporting.WinForms.ServerReportSoapProxy.OnSoapException(SoapException e)
at Microsoft.Reporting.WinForms.Internal.Soap.ReportingServices2005.Execution.RSExecutionConnection.ProxyMethodInvocation.Execute[TReturn](RSExecutionConnection connection, ProxyMethod`1 initialMethod, ProxyMethod`1 retryMethod)
at Microsoft.Reporting.WinForms.Internal.Soap.ReportingServices2005.Execution.RSExecutionConnection.LoadReport(String Report, String HistoryID)
at Microsoft.Reporting.WinForms.ServerReport.EnsureExecutionSession()
at Microsoft.Reporting.WinForms.ServerReport.SetParameters(IEnumerable`1 parameters)
at Microsoft.ConfigurationManagement.AdminConsole.SrsReporting.ReportViewerWindowsForms.SetParameterValues_DoWork(Object sender, DoWorkEventArgs e)

I couldn’t find what is the issue, I was doing it with the ReportSync tool I have read about here:

But there was nothing about that error :/ so I was searching further and found that great article, it is quite similar buuut… it has explanation of how to get rid of thta error 🙂

Blog is written as a one page so you have to search by “Migrate the SCCM 2007 reports to SCCM 2012” header.

In case the website was no longer available – you have to do the fallowing after migration:

1. Go to to website http://<your_sqlreporting_server>/reports

2. Go to report that you have problem with

3. Click on it – so you will have error on the screen

4. Click on the report name on the top of the page (for ex. if your path to the report on the top looks like “Home > ConfigMgr_WRO > Asset Intelligence > Hardware 01A – Summary of computers in a specific collection” <- click on the bolded name) – it will lead you to the properties of the report.

5. Change the datasource of the report – don’t worry if the “test connecion” won’t work.

6. Go to report and run it 🙂 it should be all fine

Unfortunatelly I have had about hundreds of reports to correct the data source, figuring out the script was the priority 🙂 I have found a great script on that website:

For me it was like:

$newDataSourcePath = "/ConfigMgr_WRO/{5C6358F2-4BB6-4a1b-A16E-8D96795D8602}";
$newDataSourceName = "AutoGen__5C6358F2_4BB6_4a1b_A16E_8D96795D8602_";
$SiteCode = "WRO"
$serverName = "WRO&lt;span style="font-size: small;"&gt;SCCM&lt;/span&gt;"
$reportFolder = "/ConfigMgr&lt;span style="font-size: small;"&gt;_&lt;span style="font-size: small;"&gt;WRO&lt;/span&gt;&lt;/span&gt;/ConfigMgr_&lt;span style="font-size: small;"&gt;OldSite&lt;/span&gt;";

$ssrs = New-WebServiceProxy -uri http://$serverName/ReportServer/ReportService2005.asmx?WSDL -UseDefaultCredential

$reports = $ssrs.ListChildren($reportFolder, $True)

$reports | ForEach-Object {

$reportPath = $_.path

$dataSources = $ssrs.GetItemDataSources($reportPath)
$dataSources | ForEach-Object {

$proxyNamespace = $_.GetType().Namespace
$myDataSource = New-Object ("$proxyNamespace.DataSource")
$myDataSource.Name = $newDataSourceName
$myDataSource.Item = New-Object ("$proxyNamespace.DataSourceReference")
$myDataSource.Item.Reference = $newDataSourcePath
$_.item = $myDataSource.Item
$ssrs.SetItemDataSources($reportPath, $_)
Write-Host "Report's DataSource Reference ($($_.Name)): $($_.Item.Reference)";


The script will modify all reports in the “$reportFolder” and it’s subfolders! Isn’t it great!?