locked
duplicate/copy task sequence with powershell RRS feed

  • Question

  • Hi,

    I need to copy a template task sequence with powershell. With Export-CMTaskSequence/Import-CMTaskSequence you can't change the name.

    I would need a function like: duplicate_tasksequence ( $templateTSName, $newTSName) - like "copy" in SCCM Console...

    Many thanks in advanced.


    Thursday, February 21, 2013 9:24 AM

Answers

  • Finally I got the solution like this. I'm pretty sure there is a better solution but for me it works:

    $siteServer = "localhost"
    $siteCode = "CM1"
    
    function duplicate_tasksequence ($origTSName,$newTSName) {
        try
        {
    		$ns_root = "ROOT\SMS\Site_$sitecode"
    		$origTSPkg = GWMI -ComputerName $siteServer -Namespace $ns_root -Class "SMS_TaskSequencePackage" -Filter "Name='$origTSName'"
    
            # check if we found task sequence
            if ($origTSPkg.PackageID -ne "")
            {
    			$methodTSPkgName = "SMS_TaskSequencePackage"
    			$mc = [WMIClass]"$($ns_root):$($methodTSPkgName)"
    			$inParamsGet = $mc.psbase.GetMethodParameters("GetSequence")
    			$inParamsGet.TaskSequencePackage = $origTSPkg
    			$outParamsGet = $mc.psbase.InvokeMethod("GetSequence",$inparamsGet,$null)
    			
    			$newTS = $outParamsGet.TaskSequence
    			$newTSPkg = ([WMIClass]"$($ns_root):$($methodTSPkgName)").CreateInstance()
    			$newTSPkgID = $newTSPkg.PackageID
    			$newTSPkg = $origTSPkg
    			$newTSPkg.Name = $newTSName
    			$newTSPkg.PackageID = $newTSPkgID
    			$inParamsSet = $mc.psbase.GetMethodParameters("SetSequence")
    			$inParamsSet.TaskSequence = $newTS
    			$inParamsSet.TaskSequencePackage = $newTSPkg
    			$outParamsSet = $mc.psbase.InvokeMethod("SetSequence",$inParamsSet,$null)
    			
    			$ntsPkg = GWMI -ComputerName $siteServer -Namespace $ns_root -Class "SMS_TaskSequencePackage" | where { $outParamsSet.SavedTaskSequencePackagePath.Contains($_.PackageID)}
    			return $ntsPkg.PackageID
            }
            else
            {
                return ""
            }
        }
        catch
        {
            return null;
        }
    }
    
    $newTSId = duplicate_tasksequence "templateTS" "newCopiedTS"
    
    
    

    Thanks for any comments on this.

    • Marked as answer by Wolfgang Bäck Saturday, February 23, 2013 5:07 PM
    Saturday, February 23, 2013 5:07 PM

All replies

  • Hi, Wolfgang. This is a great idea and I would suggest filing this as a feedback item on Connect at https://connect.microsoft.com/ConfigurationManagervnext/Feedback so this can be considered for a future release.
    Thursday, February 21, 2013 7:02 PM
  • Hi Adam. Thanks. I will do this.

    But any idea how to do this at the moment with powershell? I have a function in C# for this - but I'm new to powershell and would need a function for this. Please help!

    Thursday, February 21, 2013 10:17 PM
  • Hi Wolfgang,

    wouldn't this be something you are looking for?

    http://www.david-obrien.net/2012/09/29/how-to-backup-restore-your-tasksequenceconfiguration-manager-2012-and-powershell/

    I provide a command to "Export" the XML Information of an existing Task sequence and a script to then Import the XML to a new Task Sequence.

    Hope that helps!


    David O'Brien | MCITP/MCSE/MCSA, CCEE/CCIA | My blog: www.david-obrien.net | me on Twitter: @david_obrien | sepago GmbH

    Friday, February 22, 2013 9:03 AM
  • Hi David

    Thanks for your reply. I saw your blog entries and I learned really a lot of them. Many Thanks.

    The problem I have with Import-CMTaskSequence that you need an UNC-path. 

    I'm writing an extension for SCCM console in the form of a powershell GUI, so I was thinking more of WMI commands.
    I am new to powershell and I have already done this with C#, but does not know how to do that with powershell.

    In C# it looks like:

    string strTaskseqID = "";
    
    IResultObject taskSequences = wqlConn.QueryProcessor.ExecuteQuery("select * from SMS_TaskSequencePackage where Name = \"" + strOrigTaskSeqName + "\"");
    
    foreach (IResultObject ro in taskSequences)
    {
    	ro.Get();
    	strTaskseqID = ro["PackageID"].StringValue;
    }
    
    // check if we found task sequence
    if (strTaskseqID != "")
    {
    	//Get instance of original Task Sequence
    	IResultObject originalTaskSequencePackage = wqlConn.GetInstance("SMS_TaskSequencePackage.PackageID='" + strTaskseqID + "'");
    	//Create new Task Sequence and get the Task Sequence from original Package
    	IResultObject newTaskSequence = null;
    	Dictionary<string, object> parameters = new Dictionary<string, object>();
    	parameters.Add("TaskSequencePackage", originalTaskSequencePackage);
    	IResultObject outParams = wqlConn.ExecuteMethod("SMS_TaskSequencePackage", "GetSequence", parameters);
    	newTaskSequence = outParams.GetSingleItem("TaskSequence");
    	//Create new Task Sequence Package instance
    	IResultObject newTaskSequencePackage = wqlConn.CreateInstance("SMS_TaskSequencePackage");
    	//Save the ID of Task Sequence Package, should be empty (= "")
    	string tspID = newTaskSequencePackage["PackageID"].StringValue;
    	//Save original properties to new Task Sequence Package
    	newTaskSequencePackage = originalTaskSequencePackage;
    	//Overwrite old name with new
    	newTaskSequencePackage["Name"].StringValue = strNewTaskSeqName;
    	//Overwrite old ID with new (clear)
    	newTaskSequencePackage["PackageID"].StringValue = tspID;
    	Dictionary<string, object> parameters2 = new Dictionary<string, object>();
    	parameters2.Add("TaskSequence", newTaskSequence);
    	parameters2.Add("TaskSequencePackage", newTaskSequencePackage);
    	//Save the new Task Sequence Package
    	IResultObject outParams2 = wqlConn.ExecuteMethod("SMS_TaskSequencePackage", "SetSequence", parameters2);
    	//Return the saved package path for further use
    	string strTSPath = outParams2["SavedTaskSequencePackagePath"].StringValue;
    	// check for new task sequence existence
    	IResultObject ntspkgID = wqlConn.GetInstance(strTSPath);
    	ntspkgID.Get();
    	return ntspkgID["PackageID"].StringValue;
    }
    else
    {
    	return "";
    }
    


    For more immediate help I would be very grateful.

    Friday, February 22, 2013 9:36 AM
  • Finally I got the solution like this. I'm pretty sure there is a better solution but for me it works:

    $siteServer = "localhost"
    $siteCode = "CM1"
    
    function duplicate_tasksequence ($origTSName,$newTSName) {
        try
        {
    		$ns_root = "ROOT\SMS\Site_$sitecode"
    		$origTSPkg = GWMI -ComputerName $siteServer -Namespace $ns_root -Class "SMS_TaskSequencePackage" -Filter "Name='$origTSName'"
    
            # check if we found task sequence
            if ($origTSPkg.PackageID -ne "")
            {
    			$methodTSPkgName = "SMS_TaskSequencePackage"
    			$mc = [WMIClass]"$($ns_root):$($methodTSPkgName)"
    			$inParamsGet = $mc.psbase.GetMethodParameters("GetSequence")
    			$inParamsGet.TaskSequencePackage = $origTSPkg
    			$outParamsGet = $mc.psbase.InvokeMethod("GetSequence",$inparamsGet,$null)
    			
    			$newTS = $outParamsGet.TaskSequence
    			$newTSPkg = ([WMIClass]"$($ns_root):$($methodTSPkgName)").CreateInstance()
    			$newTSPkgID = $newTSPkg.PackageID
    			$newTSPkg = $origTSPkg
    			$newTSPkg.Name = $newTSName
    			$newTSPkg.PackageID = $newTSPkgID
    			$inParamsSet = $mc.psbase.GetMethodParameters("SetSequence")
    			$inParamsSet.TaskSequence = $newTS
    			$inParamsSet.TaskSequencePackage = $newTSPkg
    			$outParamsSet = $mc.psbase.InvokeMethod("SetSequence",$inParamsSet,$null)
    			
    			$ntsPkg = GWMI -ComputerName $siteServer -Namespace $ns_root -Class "SMS_TaskSequencePackage" | where { $outParamsSet.SavedTaskSequencePackagePath.Contains($_.PackageID)}
    			return $ntsPkg.PackageID
            }
            else
            {
                return ""
            }
        }
        catch
        {
            return null;
        }
    }
    
    $newTSId = duplicate_tasksequence "templateTS" "newCopiedTS"
    
    
    

    Thanks for any comments on this.

    • Marked as answer by Wolfgang Bäck Saturday, February 23, 2013 5:07 PM
    Saturday, February 23, 2013 5:07 PM