PowerShell script to create a SCCM Package,Program and Queries

I wanted to automate the process of creating a new package. The following code will look at an XML file for values (same xml file I am using here) and create a package based on the values. A lot of SCCM PowerShell was gathered from here. Here is the example of the source XML file:

<Install>
<Params>
<PkgName Value="Firefox" />
<PkgManufacturer Value="Mozilla" />
<PkgVersion Value="12.0" />
<PkgSourcePath Value="\\domain.local\DFSRoot\Path\Mozilla\Firefox-12.0" />
<PkgcontainerNodeID Value="17" />
<CurrentVersionQueryName Value="Software-MozillaFirefox-12.0" />
<OtherThanQueryName Value="Software-MozillaFirefox-OtherThan-12.0" />
<QuerycontainerNodeID Value="4" />
</Params>
</Install>

And here is the script that creates the package, program, distribution point,and 2 queries (A query to show where version is installed, and a second to show where it is not installed (NOT IN).)

function JBMMURPHY-SCCM-CreatePackageAndQueries{
PARAM(
    [Parameter(Mandatory=$true)]
    [ValidateScript({Test-Path $_})]
    $XMLFilePath)
[ xml ]$s = Get-Content $XMLFilePath

$NAMESPACE="root\SMS\Site_LAB"
$PkgName=$s.Install.SCCMParams.PkgName.Value
$PkgManufacturer=$s.Install.SCCMParams.PkgManufacturer.Value
$PkgVersion=$s.Install.SCCMParams.PkgVersion.Value
$PkgSourcePath=$s.Install.SCCMParams.PkgSourcePath.Value
$PkgcontainerNodeID=$s.Install.SCCMParams.PkgcontainerNodeID.Value
$OtherThanQueryName=$s.Install.SCCMParams.OtherThanQueryName.Value
$CurrentVersionQueryName=$s.Install.SCCMParams.CurrentVersionQueryName.Value
$QuerycontainerNodeID=$s.Install.SCCMParams.QuerycontainerNodeID.Value
$PkgProgramFlags=135308289
$PkgCommandLine = "powershell .\SVCInstall.ps1"

## create package and move into appropriate folder
$PackageProperties = @{
Name = $PkgName;
Manufacturer = $PkgManufacturer;
Version = $PkgVersion;
Language = "English (United States)";
PackageType = 0;
PkgSourceFlag = 2;
PkgSourcePath = $PkgSourcePath
Priority = 2
}
$newPackage = Set-WmiInstance -class SMS_Package -arguments $PackageProperties -namespace $NAMESPACE
$newPackage | Format-List | Out-Null
write-host "pkgid=$($newPackage.PackageID)"

## Move Package
$MovePackage = @{
InstanceKey = $newPackage.PackageID;
ObjectType = 2;
ContainerNodeID = $PkgcontainerNodeID
}
Set-WmiInstance -Class SMS_ObjectContainerItem -arguments $MovePackage -namespace $NAMESPACE

## create new program = Per-system unattended

$NewProgram = @{
PackageID = $newPackage.PackageID;
ProgramFlags = $PkgProgramFlags;
ProgramName = "Per-system unattended";
CommandLine = $PkgCommandLine
}
Set-WmiInstance -class SMS_Program -arguments $NewProgram -namespace $NAMESPACE

## Add Distribution point to package

$NewDistPointForPackage = @{
PackageID = $newPackage.PackageID;
ServerNALPath = '["Display=\\SERVENAME\"]MSWNET:["SMS_SITE=LAB"]\\SERVERNAME\';
SiteCode = "LAB";
SiteName = "LAB";
SourceSite = "LAB";
ResourceType = "Windows NT Server"
}
Set-WmiInstance -class SMS_DistributionPoint -arguments $NewDistPointForPackage -namespace $NAMESPACE


## Creating Queries

## Current Verson Query
$CurrentVersionQuery="select SMS_R_System.Name, SMS_R_System.LastLogonUserName, SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName, SMS_G_System_ADD_REMOVE_PROGRAMS.Version from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId where SMS_R_System.Client = 1 and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like `'$($PkgName)%`' and SMS_G_System_ADD_REMOVE_PROGRAMS.Version = `'$($PkgVersion)`' order by SMS_R_System.Name";
$CurrentVersionQueryHash = @{
Name = $CurrentVersionQueryName;
Expression = $CurrentVersionQuery;
TargetClassName = "SMS_R_System"
}
$newCurrentVersionQuery = Set-WmiInstance -class SMS_Query -arguments $CurrentVersionQueryHash -namespace $NAMESPACE
$newCurrentVersionQuery  | Format-List | Out-Null

$MoveCurrentVersionQuery=@{
InstanceKey = $newCurrentVersionQuery.QueryID;
ObjectType = 7;
ContainerNodeID = $QuerycontainerNodeID
}
Set-WmiInstance -Class SMS_ObjectContainerItem -arguments $MoveCurrentVersionQuery -namespace $NAMESPACE


## Other Than Query
$OtherThanQuery="select SMS_R_System.Name, SMS_R_System.LastLogonUserName, SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName, SMS_G_System_ADD_REMOVE_PROGRAMS.Version from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId where SMS_R_System.Client = 1 and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like `'$($PkgName)%`' and SMS_R_System.Name not in (select SMS_R_System.Name from  SMS_R_System inner join SMS_G_System_ADD_REMOVE_PROGRAMS on SMS_G_System_ADD_REMOVE_PROGRAMS.ResourceID = SMS_R_System.ResourceId where SMS_R_System.Client = 1 and SMS_G_System_ADD_REMOVE_PROGRAMS.DisplayName like `'$($PkgName)%`' and SMS_G_System_ADD_REMOVE_PROGRAMS.Version = `'$($PkgVersion)`') order by SMS_R_System.Name"
$OtherThanQueryHash =@{
Name = $OtherThanQueryName;
Expression = $OtherThanQuery;
TargetClassName = "SMS_R_System"
}
$newOtherThanQuery = Set-WmiInstance -class SMS_Query -arguments $OtherThanQueryHash -namespace $NAMESPACE
$newOtherThanQuery  | Format-List | Out-Null

$MoveOtherThanQuery=@{
InstanceKey = $newOtherThanQuery.QueryID;
ObjectType = 7;
ContainerNodeID = $QuerycontainerNodeID
}
Set-WmiInstance -Class SMS_ObjectContainerItem -arguments $MoveOtherThanQuery -namespace $NAMESPACE

# To Find Node: gwmi -Namespace $NAMESPACE -query "Select * from SMS_ObjectContainerNode WHERE Name = 'ContainerName'"
# Example run: JBMURPHY-SCCM-CreatePackage -XMLFilePath \\domain.local\DFSRoot\Path\Install.xml
#
}

,

6 Responses to PowerShell script to create a SCCM Package,Program and Queries

  1. ssake November 30, 2012 at 8:52 am #

    I Made xml files and change site code and other .
    I can run script but nothing hepening.
    Can Anyvone give me dummies guides for this.

    Kind Regards
    Savo

  2. jbmurphy December 5, 2012 at 4:12 pm #

    Not sure, you did not give me enough to go on. I was running this from the SCCM 2007 server, if that helps

  3. samuel January 4, 2013 at 8:13 am #

    Hello Jbmurphy

    First of all I em beginer with powershell
    I try to use your script to create function som read information from XML files .
    Her is my input what I did-I em not sure em I did right.
    I try to Use Put() -method
    I em using sccm 2012 sp1

    function New-Sccmpackage {
        [CmdletBinding()]
        param (
              [Parameter(Mandatory = $true)]
              [string] $SccmServer
            , [Parameter(Mandatory = $true)]
              [ValidateLength(3,3)]
              [string] $SiteCode
            , [Parameter(Mandatory = $true)]
              [string] $packageName
            , [Parameter(Mandatory = $true)]
              [string] $packageDescription
    , [Parameter(Mandatory = $true)]
              [string] $packageVersion
    , [Parameter(Mandatory = $true)]
              [string] $packageManufacturer
    , [Parameter(Mandatory = $true)]
              [string] $packageLanguage
    , [Parameter(Mandatory = $true)]
              [string] $packageSource
        )
        
        {
    $PackageList = Get-CimInstance -Namespace “root\sms\site_$SiteCode” -ClassName SMS_Package;
    $newPkg = $PackageList.CreateInstance()
    $newPkg.Name = $item.PackageName
    $newPkg.Manufacturer = $item.PackageManufacturer
    $newPkg.Version = $item.PackageVersion
    $newPkg.Language = $item.PackageLanguage
    $newPkg.Description = $item.PackageComment
    $newPkg.PackageType = 0
    $newPkg.PkgSourceFlag = 2
    $newPkg.PkgSourcePath = $item.PackageSourcePath
    $newPkg.Priority = 2
    $pkgPath = $newPkg.Put()

    I em not good to powershell

    I did this to find infomation about medtod

    $pkgoffice =Get-CimInstance -Namespace “root\sms\site_P01” -ClassName SMS_Package -Filter “Name like ‘Office%'”

    $pkgoffice | Get-Member -View all

    I found method Put()
    I found InvokeMethod.

    I em not shure what i should use

    Get-WmiObject cmdlet—this was read-only access to WMI,
    Get-WmiObject it could also be used to create an object from which you could call methods.

    SET-WMIINSTANCE

    cmdlet to create new WMI instances is of limited practical use. I don’t recommend
    using Set-WmiInstance for anything but modifying the properties of existing objects.

    Invoke-WmiMethod

    $pkgoffice =gwmi -computer sccm13 -namespace root\sms\site_P01 -class sms_package

    $pkgoffice | Get-Member -MemberType method

    One of the methods is Put or InvokeMethod. I look at the documentation SDK is not many information indicates what you need for det method.

    Please Help

  4. jbmurphy February 15, 2013 at 2:29 pm #

    I am not sure. If I come across something I will reply back. Sorry.

Trackbacks/Pingbacks

  1. Creating a ConfigMgr package, a program and queries using PowerShell - May 10, 2012

    […] Read the full post: PowerShell script to create a SCCM Package,Program and Queries […]

  2. SCCM: Powershell scripting « MS Tech BLOG - May 10, 2012

    […] http://www.jbmurphy.com/2012/05/10/powershell-script-to-create-a-sccm-packageprogram-and-queries/ […]