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
#
}

Posted

in

,

by

Tags:

Comments

6 responses to “PowerShell script to create a SCCM Package,Program and Queries”

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

  2. ssake Avatar
    ssake

    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

  3. jbmurphy Avatar

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

  4. samuel Avatar
    samuel

    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

  5. jbmurphy Avatar

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