SCCM PoSH

Changelog

  • 2013-05-09 (Ricardo Cheing)
    Bugfix: Add-SCCMDirUserCollectionRule (Corrected Get-User to Get-SCCMUser)
  • 2010-10-29 (Rikard Ronnkvist)
    New functions: Update-SCCMDriverPkgSourcePath, Update-SCCMPackageSourcePath, Update-SCCMDriverSourcePath
  • 2010-10-06 (Stefan Ringler)
    New and updated functions from http://www.stefanringler.com/?p=150 (New-SCCMPackage, New-SCCMAdvertisement, New-SCCMProgram, Add-SCCMDistributionPoint)
  • 2010-09-13 (Rikard Ronnkvist)
    Bugfix: Get-SCCMCollectionMembers (Thanks to Milos)
    Bugfix: Add-SCCMCollectionRule (Thanks to Luigi)
  • 2010-03-26 (Rikard Ronnkvist)
    Separate page on snowland.se
    New function: New-SCCMPackage
  • 2010-03-23 (Rikard Ronnkvist)
    Fixed some small bugs
    Added limitToCollectionId in Add-SCCMCollectionRule
  • 2010-03-10 (Rikard Ronnkvist)
    Major makeover
    First snowland.se release
  • 2009-04-07 (Michael Niehaus)
    Original code posted at http://blogs.technet.com/mniehaus/

Usage:

  • Save the file as SCCM-Commands.psm1
  • PS:>Import-Module SCCM-Commands
  • PS:>Get-SCCMCommands

SCCM-Commands.psm1

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#                                                                                                                            Rikard Ronnkvist / snowland.se
#  Usage:
#   Save the file as SCCM-Commands.psm1
#   PS:>Import-Module SCCM-Commands
#   PS:>Get-SCCMCommands
#
#  2009-04-07   Michael Niehaus     Original code posted at http://blogs.technet.com/mniehaus/
#  2010-03-10   Rikard Ronnkvist    Major makeover and first snowland.se release
#  2010-03-23   Rikard Ronnkvist    Fixed some small bugs and added limitToCollectionId in Add-SCCMCollectionRule
#  2010-03-26   Rikard Ronnkvist    New function: New-SCCMPackage
#  2010-09-13   Rikard Ronnkvist    Bugfixes to Add-SCCMCollectionRule and Get-SCCMCollectionMembers (Thanks to comments on snowland.se from Milos and Luigi)
#  2010-10-06   Stefan Ringler      New and updated functions from http://www.stefanringler.com/?p=150 (New-SCCMPackage, New-SCCMAdvertisement, New-SCCMProgram, Add-SCCMDistributionPoint)
#  2010-10-29   Rikard Ronnkvist    New functions: Update-SCCMDriverPkgSourcePath, Update-SCCMPackageSourcePath, Update-SCCMDriverSourcePath
#  2013-05-09   Ricardo Cheing      Bugfix: Add-SCCMDirUserCollectionRule (Corrected Get-User to Get-SCCMUser)
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function Get-SCCMCommands {
	# List all SCCM-commands
	[CmdletBinding()]
	PARAM ()
	PROCESS {
		return Get-Command -Name *-SCCM* -CommandType Function  | Sort-Object Name | Format-Table Name, Module
	}
}

Function Connect-SCCMServer {
	# Connect to one SCCM server
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$false,HelpMessage="SCCM Server Name or FQDN",ValueFromPipeline=$true)][Alias("ServerName","FQDN","ComputerName")][String] $HostName = (Get-Content env:computername),
		[Parameter(Mandatory=$false,HelpMessage="Optional SCCM Site Code",ValueFromPipelineByPropertyName=$true )][String] $siteCode = $null,
		[Parameter(Mandatory=$false,HelpMessage="Credentials to use" )][System.Management.Automation.PSCredential] $credential = $null
	)

	PROCESS {
		# Get the pointer to the provider for the site code
		if ($siteCode -eq $null -or $siteCode -eq "") {
			Write-Verbose "Getting provider location for default site on server $HostName"
			if ($credential -eq $null) {
				$sccmProviderLocation = Get-WmiObject -query "select * from SMS_ProviderLocation where ProviderForLocalSite = true" -Namespace "root\sms" -computername $HostName -errorAction Stop
			} else {
				$sccmProviderLocation = Get-WmiObject -query "select * from SMS_ProviderLocation where ProviderForLocalSite = true" -Namespace "root\sms" -computername $HostName -credential $credential -errorAction Stop
			}
		} else {
			Write-Verbose "Getting provider location for site $siteCode on server $HostName"
			if ($credential -eq $null) {
				$sccmProviderLocation = Get-WmiObject -query "SELECT * FROM SMS_ProviderLocation where SiteCode = '$siteCode'" -Namespace "root\sms" -computername $HostName -errorAction Stop
			} else {
				$sccmProviderLocation = Get-WmiObject -query "SELECT * FROM SMS_ProviderLocation where SiteCode = '$siteCode'" -Namespace "root\sms" -computername $HostName -credential $credential -errorAction Stop
			}
		}

		# Split up the namespace path
		$parts = $sccmProviderLocation.NamespacePath -split "\\", 4
		Write-Verbose "Provider is located on $($sccmProviderLocation.Machine) in namespace $($parts[3])"

		# Create a new object with information
		$retObj = New-Object -TypeName System.Object
		$retObj | add-Member -memberType NoteProperty -name Machine -Value $HostName
		$retObj | add-Member -memberType NoteProperty -name Namespace -Value $parts[3]
		$retObj | add-Member -memberType NoteProperty -name SccmProvider -Value $sccmProviderLocation

		return $retObj
	}
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function Get-SCCMObject {
	#  Generic query tool
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipelineByPropertyName=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="SCCM Class to query",ValueFromPipeline=$true)][Alias("Table","View")][String] $class,
		[Parameter(Mandatory=$false,HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		if ($Filter -eq $null -or $Filter -eq "")
		{
			Write-Verbose "WMI Query: SELECT * FROM $class"
			$retObj = get-wmiobject -class $class -computername $SccmServer.Machine -namespace $SccmServer.Namespace
		}
		else
		{
			Write-Verbose "WMI Query: SELECT * FROM $class WHERE $Filter"
			$retObj = get-wmiobject -query "SELECT * FROM $class WHERE $Filter" -computername $SccmServer.Machine -namespace $SccmServer.Namespace
		}

		return $retObj
	}
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function Get-SCCMPackage {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_Package" -Filter $Filter
	}
}

Function Get-SCCMCollection {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_Collection" -Filter $Filter
	}
}

Function Get-SCCMAdvertisement {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_Advertisement" -Filter $Filter
	}
}

Function Get-SCCMDriver {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_Driver" -Filter $Filter
	}
}

Function Get-SCCMDriverPackage {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_DriverPackage" -Filter $Filter
	}
}

Function Get-SCCMTaskSequence {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_TaskSequence" -Filter $Filter
	}
}

Function Get-SCCMSite {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_Site" -Filter $Filter
	}
}

Function Get-SCCMImagePackage {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_ImagePackage" -Filter $Filter
	}
}

Function Get-SCCMOperatingSystemInstallPackage {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_OperatingSystemInstallPackage" -Filter $Filter
	}
}

Function Get-SCCMBootImagePackage {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Optional Filter on query")][String] $Filter = $null
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_BootImagePackage" -Filter $Filter
	}
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function Get-SCCMComputer {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Filter on SCCM Resource ID",ValueFromPipelineByPropertyName=$true)][int32] $ResourceID = $false,
		[Parameter(Mandatory=$false, HelpMessage="Filter on Netbiosname on computer",ValueFromPipeline=$true)][String] $NetbiosName = "%",
		[Parameter(Mandatory=$false, HelpMessage="Filter on Domain name",ValueFromPipelineByPropertyName=$true)][Alias("Domain", "Workgroup")][String] $ResourceDomainOrWorkgroup = "%",
		[Parameter(Mandatory=$false, HelpMessage="Filter on SmbiosGuid (UUID)")][String] $SmBiosGuid = "%"
	)

	PROCESS {
		if ($ResourceID -eq $false -and $NetbiosName -eq "%" -and $ResourceDomainOrWorkgroup -eq "%" -and $SmBiosGuid -eq "%") {
			throw "Need at least one filter..."
		}

		if ($ResourceID -eq $false) {
			return Get-SCCMObject -sccmServer $SccmServer -class "SMS_R_System" -Filter "NetbiosName LIKE '$NetbiosName' AND ResourceDomainOrWorkgroup LIKE '$ResourceDomainOrWorkgroup' AND SmBiosGuid LIKE '$SmBiosGuid'"
		} else {
			return Get-SCCMObject -sccmServer $SccmServer -class "SMS_R_System" -Filter "ResourceID = $ResourceID"
		}
	}
}

Function Get-SCCMUser {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Filter on SCCM Resource ID",ValueFromPipelineByPropertyName=$true)][int32] $ResourceID = $false,
		[Parameter(Mandatory=$false, HelpMessage="Filter on unique username in form DOMAIN\UserName",ValueFromPipelineByPropertyName=$true)][String] $UniqueUserName = "%",
		[Parameter(Mandatory=$false, HelpMessage="Filter on Domain name",ValueFromPipelineByPropertyName=$true)][Alias("Domain")][String] $WindowsNTDomain = "%",
		[Parameter(Mandatory=$false, HelpMessage="Filter on UserName",ValueFromPipeline=$true)][String] $UserName = "%"
	)

	PROCESS {
		if ($ResourceID -eq $false -and $UniqueUserName -eq "%" -and $WindowsNTDomain -eq "%" -and $UserName -eq "%") {
			throw "Need at least one filter..."
		}

		if ($ResourceID -eq $false) {
			return Get-SCCMObject -sccmServer $SccmServer -class "SMS_R_User" -Filter "UniqueUserName LIKE '$UniqueUserName' AND WindowsNTDomain LIKE '$WindowsNTDomain' AND UserName LIKE '$UserName'"
		} else {
			return Get-SCCMObject -sccmServer $SccmServer -class "SMS_R_User" -Filter "ResourceID = $ResourceID"
		}
	}
}

Function Get-SCCMCollectionMembers {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="CollectionID", ValueFromPipeline=$true)][String] $CollectionID
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_CollectionMember_a" -Filter "CollectionID = '$CollectionID'"
	}
}

Function Get-SCCMSubCollections {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="CollectionID",ValueFromPipeline=$true)][Alias("parentCollectionID")][String] $CollectionID
	)

	PROCESS {
		return Get-SCCMObject -sccmServer $SccmServer -class "SMS_CollectToSubCollect" -Filter "parentCollectionID = '$CollectionID'"
	}
}

Function Get-SCCMParentCollection {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="CollectionID",ValueFromPipeline=$true)][Alias("subCollectionID")][String] $CollectionID
	)

	PROCESS {
		$parentCollection = Get-SCCMObject -sccmServer $SccmServer -class "SMS_CollectToSubCollect" -Filter "subCollectionID = '$CollectionID'"

		return Get-SCCMCollection -sccmServer $SccmServer -Filter "CollectionID = '$($parentCollection.parentCollectionID)'"
	}
}

Function Get-SCCMSiteDefinition {
	# Get all definitions for one SCCM site
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer
	)

	PROCESS {
		Write-Verbose "Refresh the site $($SccmServer.SccmProvider.SiteCode) control file"
		Invoke-WmiMethod -path SMS_SiteControlFile -name RefreshSCF -argumentList $($SccmServer.SccmProvider.SiteCode) -computername $SccmServer.Machine -namespace $SccmServer.Namespace

		Write-Verbose "Get the site definition object for this site"
		return get-wmiobject -query "SELECT * FROM SMS_SCI_SiteDefinition WHERE SiteCode = '$($SccmServer.SccmProvider.SiteCode)' AND FileType = 2" -computername $SccmServer.Machine -namespace $SccmServer.Namespace
	}
}

Function Get-SCCMSiteDefinitionProps {
	# Get definitionproperties for one SCCM site
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer
	)

	PROCESS {
		return Get-SCCMSiteDefinition -sccmServer $SccmServer | ForEach-Object { $_.Props }
	}
}

Function Get-SCCMIsR2 {
	# Return $true if the SCCM server is R2 capable
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer
	)

	PROCESS {
		$result = Get-SCCMSiteDefinitionProps -sccmServer $SccmServer | ? {$_.PropertyName -eq "IsR2CapableRTM"}
		if (-not $result) {
			return $false
		} elseif ($result.Value = 31) {
			return $true
		} else {
			return $false
		}
	}
}

Function Get-SCCMCollectionRules {
	# Get a set of all collectionrules
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="CollectionID", ValueFromPipeline=$true)][String] $CollectionID
	)

	PROCESS {
		Write-Verbose "Collecting rules for $CollectionID"
		$col = [wmi]"$($SccmServer.SccmProvider.NamespacePath):SMS_Collection.CollectionID='$($CollectionID)'"

		return $col.CollectionRules
	}
}

Function Get-SCCMInboxes {
	# Give a count of files in the SCCM-inboxes
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server",ValueFromPipeline=$true)][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$false, HelpMessage="Minimum number of files in directory")][int32] $minCount = 1
	)

	PROCESS {
		Write-Verbose "Reading \\$($SccmServer.Machine)\SMS_$($SccmServer.SccmProvider.SiteCode)\inboxes"
		return Get-ChildItem \\$($SccmServer.Machine)\SMS_$($SccmServer.SccmProvider.SiteCode)\inboxes -Recurse | Group-Object Directory | Where { $_.Count -gt $minCount } | Format-Table Count, Name -AutoSize
	}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Function New-SCCMCollection {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="Collection Name", ValueFromPipeline=$true)][String] $name,
		[Parameter(Mandatory=$false, HelpMessage="Collection comment")][String] $comment = "",
		[Parameter(Mandatory=$false, HelpMessage="Refresh Rate in Minutes")] [ValidateRange(0, 59)] [int] $refreshMinutes = 0,
		[Parameter(Mandatory=$false, HelpMessage="Refresh Rate in Hours")] [ValidateRange(0, 23)] [int] $refreshHours = 0,
		[Parameter(Mandatory=$false, HelpMessage="Refresh Rate in Days")] [ValidateRange(0, 31)] [int] $refreshDays = 0,
		[Parameter(Mandatory=$false, HelpMessage="Parent CollectionID")][String] $parentCollectionID = "COLLROOT"
	)

	PROCESS {
		# Build the parameters for creating the collection
		$arguments = @{Name = $name; Comment = $comment; OwnedByThisSite = $true}
		$newColl = Set-WmiInstance -class "SMS_Collection" -arguments $arguments -computername $SccmServer.Machine -namespace $SccmServer.Namespace

		# Hack - for some reason without this we don't get the CollectionID value
		$hack = $newColl.PSBase | select * | out-null

		# It's really hard to set the refresh schedule via Set-WmiInstance, so we'll set it later if necessary
		if ($refreshMinutes -gt 0 -or $refreshHours -gt 0 -or $refreshDays -gt 0)
		{
			Write-Verbose "Create the recur interval object"
			$intervalClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_ST_RecurInterval"
			$interval = $intervalClass.CreateInstance()
			if ($refreshMinutes -gt 0) {
				$interval.MinuteSpan = $refreshMinutes
			}
			if ($refreshHours -gt 0) {
				$interval.HourSpan = $refreshHours
			}
			if ($refreshDays -gt 0) {
				$interval.DaySpan = $refreshDays
			}

			Write-Verbose "Set the refresh schedule"
			$newColl.RefreshSchedule = $interval
			$newColl.RefreshType=2
			$path = $newColl.Put()
		}   

		Write-Verbose "Setting the new $($newColl.CollectionID) parent to $parentCollectionID"
		$subArguments  = @{SubCollectionID = $newColl.CollectionID}
		$subArguments += @{ParentCollectionID = $parentCollectionID}

		# Add the link
		$newRelation = Set-WmiInstance -Class "SMS_CollectToSubCollect" -arguments $subArguments -computername $SccmServer.Machine -namespace $SccmServer.Namespace

		Write-Verbose "Return the new collection with ID $($newColl.CollectionID)"
		return $newColl
	}
}

Function Add-SCCMCollectionRule {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true,  HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true,  HelpMessage="CollectionID", ValueFromPipelineByPropertyName=$true)] $collectionID,
		[Parameter(Mandatory=$false, HelpMessage="Computer name to add (direct)", ValueFromPipeline=$true)] [String] $name,
		[Parameter(Mandatory=$false, HelpMessage="WQL Query Expression", ValueFromPipeline=$true)] [String] $queryExpression = $null,
		[Parameter(Mandatory=$false, HelpMessage="Limit to collection (Query)", ValueFromPipeline=$false)] [String] $limitToCollectionId = $null,
		[Parameter(Mandatory=$true,  HelpMessage="Rule Name", ValueFromPipeline=$true)] [String] $queryRuleName
	)

	PROCESS {
		# Get the specified collection (to make sure we have the lazy properties)
		$coll = [wmi]"$($SccmServer.SccmProvider.NamespacePath):SMS_Collection.CollectionID='$collectionID'"

		# Build the new rule
		if ($queryExpression.Length -gt 0) {
			# Create a query rule
			$ruleClass = [WMICLASS]"$($SccmServer.SccmProvider.NamespacePath):SMS_CollectionRuleQuery"
			$newRule = $ruleClass.CreateInstance()
			$newRule.RuleName = $queryRuleName
			$newRule.QueryExpression = $queryExpression
			if ($limitToCollectionId -ne $null) {
				$newRule.LimitToCollectionID = $limitToCollectionId
			}

			$null = $coll.AddMembershipRule($newRule)
		} else {
			$ruleClass = [WMICLASS]"$($SccmServer.SccmProvider.NamespacePath):SMS_CollectionRuleDirect"

			# Find each computer
			$computer = Get-SCCMComputer -sccmServer $SccmServer -NetbiosName $name
			# See if the computer is already a member
			$found = $false
			if ($coll.CollectionRules -ne $null) {
				foreach ($member in $coll.CollectionRules) {
					if ($member.ResourceID -eq $computer.ResourceID) {
						$found = $true
					}
				}
			}
			if (-not $found) {
				Write-Verbose "Adding new rule for computer $name"
				$newRule = $ruleClass.CreateInstance()
				$newRule.RuleName = $name
				$newRule.ResourceClassName = "SMS_R_System"
				$newRule.ResourceID = $computer.ResourceID

				$null = $coll.AddMembershipRule($newRule)
			} else {
				Write-Verbose "Computer $name is already in the collection"
			}
		}
	}
}

Function Add-SCCMDirUserCollectionRule {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(ValueFromPipelineByPropertyName=$true)][String] $CollectionID,
		[Parameter(ValueFromPipeline=$true)][String] $UserName
	)

	PROCESS {
		$coll = [wmi]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_Collection.CollectionID='$CollectionID'"
		$ruleClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_CollectionRuleDirect"

		$RuleClass
		$UserRule=Get-SCCMUser "userName='$UserName'"
		$NewRuleName=$UserRule.name
		$NewRuleResourceID = $UserRule.ResourceID
		$newRule = $ruleClass.CreateInstance()

		$newRule.RuleName = $NewRuleName
		$newRule.ResourceClassName = "SMS_R_User"
		$newRule.ResourceID = $NewRuleResourceID

		$null = $coll.AddMembershipRule($newRule)
		$coll.requestrefresh()
		Clear-Variable -name oldrule -errorAction SilentlyContinue
		Clear-Variable -name Coll -errorAction SilentlyContinue
	}
}

Function New-SCCMPackage {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="Package Name", ValueFromPipeline=$true)][String] $Name,

		[Parameter(Mandatory=$false, HelpMessage="Package Version")][String] $Version = "",
		[Parameter(Mandatory=$false, HelpMessage="Package Manufacturer")][String] $Manufacturer = "",
		[Parameter(Mandatory=$false, HelpMessage="Package Language")][String] $Language = "",
		[Parameter(Mandatory=$false, HelpMessage="Package Description")][String] $Description = "",
		[Parameter(Mandatory=$false, HelpMessage="Package Data Source Path")][String] $PkgSourcePath = "",
		[Parameter(Mandatory=$false, HelpMessage="Package Sharename")][String] $PkgShareName = ""
	)

	PROCESS {
		$packageClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_Package"
		$newPackage = $packageClass.createInstance() 

		$newPackage.Name = $Name
		if ($Version -ne "") 		{ $newPackage.Version = $Version }
		if ($Manufacturer -ne "") 	{ $newPackage.Manufacturer = $Manufacturer }
		if ($Language -ne "") 		{ $newPackage.Language = $Language }
		if ($Description -ne "") 	{ $newPackage.Description = $Description }

		if ($PkgSourcePath -ne "") {
			$newPackage.PkgSourceFlag = 2  # Direct (3 = Compressed)
			$newPackage.PkgSourcePath = $PkgSourcePath
			if ($PkgShareName -ne "") {
				$newPackage.ShareName = $PkgShareName
				$newPackage.ShareType = 2
			}
		} else {
			$newPackage.PkgSourceFlag = 1  # No source
			$newPackage.PkgSourcePath = $null
		}
		$newPackage.Put()

		$newPackage.Get()
		Write-Verbose "Return the new package with ID $($newPackage.PackageID)"
		return $newPackage
	}
}

Function New-SCCMAdvertisement {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true)] $AdvertisementName,
		[Parameter(Mandatory=$true)] $collectionID,
		[Parameter(Mandatory=$true)] $PackageID,
		[Parameter(Mandatory=$true)] $ProgramName,
		[Switch] $Download,
		[Parameter(Mandatory=$false, HelpMessage="YYYYMMDDhhmm")] $StartTime,
		[Parameter(Mandatory=$false, HelpMessage="YYYYMMDDhhmm")] $EndTime,
		[Parameter(Mandatory=$false, HelpMessage="YYYYMMDDhhmm")] $MandatoryTime
	)
	PROCESS {
		$strServer = $SccmServer.machine
		$strNamespace= $SccmServer.namespace
		$AdvClass = [WmiClass]("\\$strServer\" + "$strNameSpace" + ":SMS_Advertisement")
		if ($Download) {
			$RemoteClientFlags = "3152"
		} else {
			$RemoteClientFlags = "3208"
		}
		if ($StartTime -ne $null) {
			$PresentTime = $StartTime + "00.000000+***"
		} else {
			$PresentTime = "20200110000000.000000+***"
		}
		if ($EndTime -ne $null) {
			$ExpirationTime = $Endtime + "00.000000+***"
			$ExpirationTimeEnabled = $true
		} else {
			$ExpirationTime = "20200113000000.000000+***"
			$ExpirationTimeEnabled = $false
		}
		if ($MandatoryTime -ne $null) {
			$Deadline = $MandatoryTime + "00.000000+***"
		} else {
			$Deadline = $null
		}

		# Get the all the Advertisement Properties
		$newAdvertisement = $AdvClass.CreateInstance()
		$newAdvertisement.AdvertisementName = $AdvertisementName
		$newAdvertisement.CollectionID = $collectionID
		$newAdvertisement.PackageID = $PackageID
		$newAdvertisement.ProgramName = $ProgramName
		$newAdvertisement.RemoteClientFlags = $RemoteClientFlags
		$newAdvertisement.PresentTime = $PresentTime
		$newAdvertisement.ExpirationTime = $ExpirationTime
		$newAdvertisement.ExpirationTimeEnabled = $ExpirationTimeEnabled
		$newAdvertisement.Priority = "2"
		$newAdvertisement.IncludeSubCollection = $false

		# Create Advertisement
		$retval = $newAdvertisement.psbase.Put()
		if ($Deadline -ne $null) {
			# Create Mandatory Schedule
			$wmiClassSchedule = [WmiClass]("\\$strServer\" + "$strNameSpace" + ":SMS_ST_NonRecurring")
			$AssignedSchedule = $wmiClassSchedule.psbase.createinstance()
			$AssignedSchedule.starttime = $Deadline
			if ($Download) {
				$newAdvertisement.RemoteClientFlags = "9296"
			} else {
				$newAdvertisement.RemoteClientFlags = "9352"
			}
			$newAdvertisement.AssignedSchedule = $AssignedSchedule
			$newAdvertisement.AssignedScheduleEnabled = $true
			$newAdvertisement.psbase.put()
			$NewAdvertisementProperties = $newAdvertisement.AssignedSchedule
			foreach ($Adv in $NewAdvertisementProperties) {
				write-verbose "Created Advertisement. Name = $($newAdvertisement.AdvertisementName)"
				write-verbose "Created Advertisement. ID = $newAdvertisement"
				Write-Verbose "Mandatory Deadline created: $($Adv.StartTime)"
			}
		} else {
			write-verbose "Created Advertisement. Name = $($newAdvertisement.AdvertisementName)"
			write-verbose "Created Advertisement. ID = $newAdvertisement"
			write-verbose "No Mandatory-Deadline defined"
		}
	}
}

Function New-SCCMProgram {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="Program Name")][String] $PrgName = "",
		[Parameter(Mandatory=$true, HelpMessage="Program PackageID")]$PrgPackageID,
		[Parameter(Mandatory=$false, HelpMessage="Program Comment")][String] $PrgComment = "",
		[Parameter(Mandatory=$false, HelpMessage="Program CommandLine")][String] $PrgCommandLine = "",
		[Parameter(Mandatory=$false, HelpMessage="Program MaxRunTime")]$PrgMaxRunTime,
		[Parameter(Mandatory=$false, HelpMessage="Program Diskspace Requirement")]$PrgSpaceReq,
		[Parameter(Mandatory=$false, HelpMessage="Program Working Directory")][String] $PrgWorkDir = "",
		[Parameter(Mandatory=$false, HelpMessage="Program Flags")] $PrgFlags
	)
	PROCESS {
		$programClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_Program"
		$newProgram = $programClass.createInstance()
		$newProgram.ProgramName = $PrgName
		$newProgram.PackageID = $PrgPackageID
		if ($PrgComment -ne "") { $newProgram.Comment = $PrgComment }
		if ($PrgCommandLine -ne "") { $newProgram.CommandLine = $PrgCommandLine }
		if ($PrgMaxRunTime -ne $null) { $newProgram.Duration = $PrgMaxRunTime} else { $newProgram.Duration = "0" }
		if ($PrgSpaceReq -ne $null) { $newProgram.DiskSpaceReq = $PrgSpaceReq }
		if ($PrgWorkDir -ne "") { $newProgram.WorkingDirectory = $PrgWorkDir }
		if ($PrgFlags -ne $null) { $newProgram.ProgramFlags = $PrgFlags} else { $newProgram.ProgramFlags = "135290880" }
		$newProgram.Put()
		$newProgram.Get()
		Write-Verbose "Return the new program for Package $($newProgram.PackageID)"
		return $newProgram
	}
}

Function Add-SCCMDistributionPoint {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="PackageID")][String] $DPPackageID,
		[Parameter(Mandatory=$false, HelpMessage="DistributionPoint Servername")][String]$DPName = "",
		[Parameter(Mandatory=$false, HelpMessage="All DistributionPoints of SiteCode")][String] $DPsSiteCode = "",
		[Parameter(Mandatory=$false, HelpMessage="Distribution Point Group")][String] $DPGroupName = "",
		[Switch] $AllDPs
	)
	PROCESS {
		if ($DPName -ne "") {
			$Resource = Get-SCCMObject -SccmServer $SccmServer -class SMS_SystemResourceList -Filter "RoleName = 'SMS Distribution Point' and Servername = '$DPName'"
			$DPClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_DistributionPoint"
			$newDistributionPoint = $DPClass.createInstance()
			$newDistributionPoint.PackageID = $DPPackageID
			$newDistributionPoint.ServerNALPath = $Resource.NALPath
			$newDistributionPoint.SiteCode = $Resource.SiteCode
			$newDistributionPoint.Put()
			$newDistributionPoint.Get()
			Write-Verbose "Assigned Package: $($newDistributionPoint.PackageID)"
		}
		if ($DPsSiteCode -ne "") {
			$ListOfResources = Get-SCCMObject -SccmServer $SccmServer -class SMS_SystemResourceList -Filter "RoleName = 'SMS Distribution Point' and SiteCode = '$DPsSiteCode'"
			$DPClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_DistributionPoint"
			$newDistributionPoint = $DPClass.createInstance()
			$newDistributionPoint.PackageID = $DPPackageID
			foreach ($resource in $ListOfResources) {
				$newDistributionPoint.ServerNALPath = $Resource.NALPath
				$newDistributionPoint.SiteCode = $Resource.SiteCode
				$newDistributionPoint.Put()
				$newDistributionPoint.Get()
				Write-Verbose "Assigned Package: $($newDistributionPoint.PackageID)"
			}
		}
		if ($DPGroupName -ne "") {
			$DPGroup = Get-SCCMObject -sccmserver $SccmServer -class SMS_DistributionPointGroup -Filter "sGroupName = '$DPGroupName'"
			$DPGroupNALPaths = $DPGroup.arrNALPath
			$DPClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_DistributionPoint"
			$newDistributionPoint = $DPClass.createInstance()
			$newDistributionPoint.PackageID = $DPPackageID
			foreach ($DPGroupNALPath in $DPGroupNALPaths) {
				$DPResource = Get-SCCMObject -SccmServer $SccmServer -class SMS_SystemResourceList -Filter "RoleName = 'SMS Distribution Point'" | Where-Object {$_.NALPath -eq $DPGroupNALPath}
				if ($DPResource -ne $null) {
					Write-Verbose "$DPResource"
					$newDistributionPoint.ServerNALPath = $DPResource.NALPath
					Write-Verbose "ServerNALPath = $($newDistributionPoint.ServerNALPath)"
					$newDistributionPoint.SiteCode = $DPResource.SiteCode
					Write-Verbose "SiteCode = $($newDistributionPoint.SiteCode)"
					$newDistributionPoint.Put()
					$newDistributionPoint.Get()
					Write-Host "Assigned Package: $($newDistributionPoint.PackageID) to $($DPResource.ServerName)"
				} else {
					Write-Host "DP not found = $DPGroupNALPath"
				}
			}
		}
		if ($AllDPs) {
			$ListOfResources = Get-SCCMObject -SccmServer $SccmServer -class SMS_SystemResourceList -Filter "RoleName = 'SMS Distribution Point'"
			$DPClass = [WMICLASS]"\\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_DistributionPoint"
			$newDistributionPoint = $DPClass.createInstance()
			$newDistributionPoint.PackageID = $DPPackageID
			foreach ($resource in $ListOfResources) {
				$newDistributionPoint.ServerNALPath = $Resource.NALPath
				$newDistributionPoint.SiteCode = $Resource.SiteCode
				$newDistributionPoint.Put()
				$newDistributionPoint.Get()
				Write-Verbose "Assigned Package: $($newDistributionPoint.PackageID) $($newDistributionPoint.ServerNALPath)"
			}
		}
	}
}

Function Update-SCCMDriverPkgSourcePath {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="Current Path", ValueFromPipeline=$true)][String] $currentPath,
		[Parameter(Mandatory=$true, HelpMessage="New Path", ValueFromPipeline=$true)][String] $newPath
	)

	PROCESS {
		Get-SCCMDriverPackage -sccmserver $SccmServer | Where-Object {$_.PkgSourcePath -ilike "*$($currentPath)*" } | Foreach-Object {
			$newSourcePath = ($_.PkgSourcePath -ireplace [regex]::Escape($currentPath), $newPath)
			Write-Verbose "Changing from '$($_.PkgSourcePath)' to '$($newSourcePath)' on $($_.PackageID)"
			$_.PkgSourcePath = $newSourcePath
			$_.Put() | Out-Null
		}
	}
}

Function Update-SCCMPackageSourcePath {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="Current Path", ValueFromPipeline=$true)][String] $currentPath,
		[Parameter(Mandatory=$true, HelpMessage="New Path", ValueFromPipeline=$true)][String] $newPath
	)

	PROCESS {
		Get-SCCMPackage -sccmserver $SccmServer | Where-Object {$_.PkgSourcePath -ilike "*$($currentPath)*" } | Foreach-Object {
			$newSourcePath = ($_.PkgSourcePath -ireplace [regex]::Escape($currentPath), $newPath)
			Write-Verbose "Changing from '$($_.PkgSourcePath)' to '$($newSourcePath)' on $($_.PackageID)"
			$_.PkgSourcePath = $newSourcePath
			$_.Put() | Out-Null
		}
	}
}

Function Update-SCCMDriverSourcePathnotepad {
	[CmdletBinding()]
	PARAM (
		[Parameter(Mandatory=$true, HelpMessage="SCCM Server")][Alias("Server","SmsServer")][System.Object] $SccmServer,
		[Parameter(Mandatory=$true, HelpMessage="Current Path", ValueFromPipeline=$true)][String] $currentPath,
		[Parameter(Mandatory=$true, HelpMessage="New Path", ValueFromPipeline=$true)][String] $newPath
	)

	PROCESS {
		Get-SCCMDriver -sccmserver $SccmServer | Where-Object {$_.ContentSourcePath -ilike "*$($currentPath)*" } | Foreach-Object {
			$newSourcePath = ($_.ContentSourcePath -ireplace [regex]::Escape($currentPath), $newPath)
			Write-Verbose "Changing from '$($_.ContentSourcePath)' to '$($newSourcePath)' on $($_.PackageID)"
			$_.ContentSourcePath = $newSourcePath
			$_.Put() | Out-Null
		}
	}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# EOF

Examples

# List all available SCCM commands
Get-SCCMCommands

# Create an SCCM-Connection to the local server
$sccm = Connect-SCCMServer -Verbose

# Create a new collection with a querybased collection rule and a direct member
$newCollection = New-SCCMCollection -SccmServer $sccm -name "Some Collection Name" -Verbose
Add-SCCMCollectionRule -Server $sccm -collectionID $newRoot.CollectionId -queryExpression "SELECT * FROM SMS_R_System" -queryRuleName "All Systems" -Verbose
Add-SCCMCollectionRule -Server $sccm -collectionID $newRoot.CollectionId -name "COMPUTER123" -Verbose

# Count files in the inboxes
$sccm | Get-SCCMInboxes

# Get a package
$MyPackage = Get-SCCMPackage -server $sccm -filter "Name = 'Some Package Name'" 

37 comments

  1. Pingback: SCCM Module for PowerShell » snowland.se
  2. Sean

    Hi,

    Is there any way you can create a new object in SCCM using Powershell? I am trying to automate our server build process and need to add an object in to an SCCM group, an example is;

    Servername = “Test”
    MACAddress = “00:50:00:00:00:00″
    CollectionID = “UK300482″

    Is this possible?

    Many thanks,
    sean.

  3. riro

    Sean, It Shouldn’t be too hard…

    A quick search and I found this article http://devinfra-us.blogspot.com/2008/04/sccm-and-powershell-part-1.html

    So…

    $InParams = $mc.psbase.GetMethodParameters(“ImportMachineEntry”)
    
    $InParams.MACAddress = "00:50:00:00:00:00"
    $InParams.NetbiosName = "TEST"
    $InParams.OverwriteExistingRecord = $True
    

    Then search for the object with Get-SCCMComputer and add it to the collection with Add-SCCMCollectionRule

  4. Pingback: » SCCM: Determining collection refresh time using PowerShell
  5. Milos

    Thank you very much for great module !!!

    Shouldn’t line 262 be …

    return Get-SCCMObject -sccmServer $SccmServer -class "SMS_CollectionMember_a" -Filter "CollectionID = '$CollectionID'"
    
  6. Pete Zerger

    Richard, would love to see this project move to Codeplex so large customers would feel comfortable the code would always be available. and perhaps community could further your work. Love this module – nice work!

  7. Rico

    Hi,

    First off all….many thanks for giving me an excellent starting point for using Powershell with SCCM.

    Then I just want to let you knowm about an issue that I had regarding the use of alternate credentials.

    Any entered credentials were only used in the function Connect-SCCMServer and not carried on into function Get-SCCMObject.

    However, my quick fix was to add the following line in function Connect-SCCMServer

    $retObj | add-Member -memberType NoteProperty -name UserCredentials -Value $credential

    and in function Get-SCCMObject I added -Credential $SccmServer.UserCredentials at the end of each of the lines starting with $retObj = get-wmiobject….

    That did the trick for me.
    I also suspect that missing credentials might be a problem in other functions in the module. But that is yet to be tested… :-D

    Regards
    Rico

  8. riro

    Hi Rico, strange problem… I’m currently using a workstation with a low priv account that doesnt have access to SCCM at all.

    So, when Im running scripts I use $cred = get-credentials and then i connect to SCCM with those credentials. Works just fine for me…

  9. Luigi

    Hi Rikard, I’m tryng very hard, but I always receive errors on CollectionID. I’m sure they are correct.
    what I’m tryng to do is to create a script that asks for a computer name and add it to a collection. Here is the script

    $PC = Read-Host "nome computer"
    Connect-SCCMServer ecmihvsc10
    Add-SCCMDirUserCollectionRule  ecqumidt014 -collectionID RIZ0009E  -SccmServer ecmihvsc10 
    

    I get the following error

    Cannot convert value "\\\:SMS_Collection.CollectionID='RIZ0009E'" to type "System.Management.ManagementObject". Error: "Invalid parameter "
    At Y:\SCCM-Commands.psm1:line:492 char:16
      		$coll = [wmi]" <<<< \\$($SccmServer.Machine)\$($SccmServer.Namespace):SMS_Collection.CollectionID='$CollectionID'"
    

    can you help me?

  10. riro

    Hi Luigi.

    Looks like a small typo/miss in your powershell code, try this instead:

    $myserver = Connect-SCCMServer ecmihvsc10
    Add-SCCMDirUserCollectionRule ecqumidt014 -collectionID RIZ0009E -SccmServer $myserver
    

    (Define the object $myserver as a SCCM-connection, then use it when you create the direct rule)

  11. Luigi

    Hi Riro,

    thanks for your quick and useful answer. I need an explanation: Add-SCCMDirUserCollectionRule works with just user, or for computers too? I strongly need a way to add directly computers to a collection, and can-t find the way

    Thanks for help

  12. riro

    You can use Add-SCCMCollectionRule to add a direct membership. Use the “name” param to specify a computername.

  13. Luigi

    this is the script I used

    $myserver = Connect-SCCMServer ecmihvsc10
    Add-SCCMCollectionRule -collectionID RIZ0009E -name ecqumidt014 -SccmServer $myserver -queryRuleName ecqumidt014 
    

    it seems to work (no error) and in the collection -> properties -> membership ruless I find a rule that has ecqumidt014 as name, type query, unlimited, but query statement for this rule is not available, and computer name is not inside the collection

    Again thanks a lot for your help

  14. Luigi

    I did it!

    I’ve used the following script

    $pc = Read-Host "type PC name"
    $myserver = Connect-SCCMServer MYSERVER
    $query = "select *  from  SMS_R_System where SMS_R_System.NetbiosName = '$pc'"
    Add-SCCMCollectionRule -collectionID RIZ0009F -name $pc -SccmServer $myserver -queryRuleName $pc -queryExpression $query
    

    the difficult part was in declaring the query. As you can see I added another variable that contain the WQL query for the rule.

    Anyway, thanks a lot

  15. riro

    Ok, that will work… but you are not creating a direct membership. The one you are creating is a querybased membership. In a larger environment that will give the SCCM server a bit more load.

    Try to do it like this:

    $pc = Read-Host "type PC name"
    $myserver = Connect-SCCMServer MYSERVER
    Add-SCCMCollectionRule -collectionID RIZ0009F -name $pc -SccmServer $myserver -queryRuleName $pc
    

    (Add -Verbose to Add-SCCMCollectionRule to get some more info on what the script does)

  16. Luigi

    I tried, but it create a query based rule that is impossible to edit: on edit query statement…. the query statement pane contain only “A query is set but does not contain WQL”

  17. riro

    Luigi… I had to admit it, you found a bug. :-D

    Did fix it and the module is updated, so give it another go. (Works fine in my dev-environment)

  18. Luigi

    thanks for all your support. I will try it later and give you feedback

  19. Luigi

    still not working… but don’t worry… a query based just gives a little overhead, and it works fine. Additionally, I would like to share the way I used your commands

    with this script it alsa checks if the PC is existant in SCCM, and avoid creating false query

    thanks again

    Import-Module SCCM-Commands.psm1
    $pc = Read-Host "iinsert PC name"
    $myserver = Connect-SCCMServer SERVERNAME
    $pcinfo = Get-SCCMComputer -NetbiosName $pc -SccmServer $myserver 
    if ( $pcinfo -eq $null) {write-output "PC not existant"}
    else 
    {write-output "working..." 
    $query = "select *  from  SMS_R_System where SMS_R_System.NetbiosName = '$pc'"
    Add-SCCMCollectionRule -collectionID COLLECTIONNAME -name $pc -SccmServer $myserver -queryRuleName $pc -queryExpression $query
    }
    
  20. Pingback: Change Source-paths in ConfigMgr » snowland.se
  21. Jacob

    Why when you use New-SCCMPackage do you get an array of objects back.

    It always seems to have 2 object:
    [0] is System.Management.ManagementPath
    [1] is System.Management.ManagementObject#\SMS_Package

    So to get the packageID of the package you just created you end up having to do this:
    $sccmPkg = New-SCCMPackage ….blah….blah

    $sccmPkg[1].PackageID

    Why??

  22. riro

    Hi Jacob.

    Actually I havn’t tested that function to much… I had my thoughts on blogging about how to autocreate collections, packages and advertisments from information stored in a MSI-file.

    When I get the time to do that post, or I need to create some other packages, I’ll look in to it.
    (If someone have a fix for it, please share it)

  23. Trevor Sullivan

    Jacob,

    The reason you’re seeing the behavior of 2 objects being returned from New-SccmPackage, is because the package instance is being committed to the provider, and then directly after that, it’s being retrieved again. Both the Put() method on line #552 and the Get() method call on line #554 are returning objects to the PowerShell pipeline.

    The recommended fix would be to cast [void] from the Put() method call on line #552. That way, the package instance will still be committed to the provider, but the resulting object from the Put() operation will not be written to the pipeline.

    Cheers,
    Trevor Sullivan

  24. Pingback: Episode 148 – Matt Hester and Sarah Dutkiewicz « PowerScripting Podcast
  25. Pingback: Blog: Cloud: Dynamic creation of ConfigMgr collection hierarchy with query-based collections via PowerShell | Shared Content
  26. Pingback: powershelldistrict.com | New-SccmAppVPackage
  27. Pingback: Наиболее известные Powershell модули | slblogspot
  28. Pingback: [SCCM 2007] Powershell–Module de gestion (59 cmdlets) | Black Cat Deployment
  29. TheCarbonator

    Does this code also allow me to add a UserGroup to a collection?

    It would be helpful for Group based deployments.

    Also, can I use this for SCCM 2007 & SCCM 2012?

    Thanks!

  30. Tracy Conley

    I am trying to add users via PowerShell script to collections in my SCCM environment.


    Param(
    $ResourceName="AP-TSCTST-T001",
    $CollectionName="Wintel - 1st Monday 12:00 AM",
    $SiteCode="rb2",
    $SiteServer="ap-cmps-p01"
    )

    clear

    Import-Module sccm-command.psm1

    $myserver= Connect-SCCMServer -HostName $SiteServer -siteCode $SiteCode

    [string]$collectionID= (Get-SCCMCollection -SccmServer $myserver -filter "name='$collectionName'" ).collectionID

    Add-SCCMCollectionRule -SccmServer $myserver -collectionID $collectionID -queryExpression "SELECT * FROM SMS_R_System" -queryRuleName $CollectionName -Verbose -limitToCollectionId $null

    I am getting the following back from the script when it runs:

    Exception calling "AddMembershipRule" : "Generic failure "
    At \\corp.se.sempra.com\corpapps\Scripts\PSScripts\Library\sccm-command.psm1:459 char:1
    + $null = $coll.AddMembershipRule($newRule)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WMIMethodException

    I am trying to figure out what i need to do to get this working

  31. Tracy Conley

    actually i want to add computer not users to the collection

  32. riro

    The module is created for ConfigMgr 2007 and not tested with ConfigMGr 2012… and since I have done a few scripts around CM12 I know that there is a big difference in how collection membership is created.

    I would recommend you to use the bulitin modules that comes with CM12

  33. remie

    Unfortunately I cannot get this script working.

    An expression was expected after ‘(‘.
    At C:\Windows\system32\WindowsPowerShell\v1.0\Modules\sccm-commands\sccm-commands.psm1:20 char:24
    + A A A A [CmdletBinding( <<<< )]
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ExpectedExpression

    Import-Module : The specified module 'sccm-commands' was not loaded because no valid module file was found in any modul
    e directory.
    At line:1 char:14
    + Import-Module <<<< sccm-commands
    + CategoryInfo : ResourceUnavailable: (sccm-commands:String) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

  34. Russ

    Hi, I’m having some trouble with this, and I would appreciate any help you can give. I’m running the following script as a local admin on the SCCM 2007 primary site server.

    ***********
    Import-Module C:\Blah\SCCM-Commands.psm1
    $SccmServer = “AU-GLB-SCM02″
    $connecttoserver = Connect-SCCMServer -HostName $SccmServer -sitecode GL1
    $newcollection = New-SCCMCollection -SccmServer $SccmServer -name “$adsite.site” -comment “$adsite.comment” -parentCollectionID “$adsite.parentcollection” -Verbose
    $newqueryrule = Add-SCCMCollectionRule -Server $SccmServer -collectionID $newRoot.CollectionId -queryExpression “select * from SMS_R_System inner join SMS_G_System_SYSTEM_ENCLOSURE on SMS_G_System_SYSTEM_ENCLOSURE.ResourceId = SMS_R_System.ResourceId inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_System.ResourceId where SMS_R_System.ADSiteName = “$adsite.site” and SMS_G_System_SYSTEM_ENCLOSURE.ChassisTypes in (“8″,”9″,”10″,”11″,”12″,”14″,”18″,”21″) and SMS_G_System_COMPUTER_SYSTEM.Manufacturer not like “%VMware%”” -queryRuleName “$adsite.site” -limitToCollectionId “GL100A0B” -Verbose
    $adsites = Import-CSV C:\Blah\test.CSV
    foreach($adsite in $adsites)
    {
    $newcollection
    $newqueryrule
    }
    *****************
    I’m getting the following error:

    *****************
    Set-WmiInstance : Cannot validate argument on parameter ‘ComputerName’. The argument is null or empty. Supply an argume
    nt that is not null or empty and then try the command again.
    At C:\Blah\SCCM-Commands.psm1:394 char:95
    + $newColl = Set-WmiInstance -class “SMS_Collection” -arguments $arguments -computername <<<< $SccmServer.Mach
    ine -namespace $SccmServer.Namespace
    + CategoryInfo : InvalidData: (:) [Set-WmiInstance], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SetWmiInstance

    VERBOSE: Setting the new parent to .parentcollection
    Set-WmiInstance : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Supply an argume
    nt that is not null or empty and then try the command again.
    At C:\Blah\SCCM-Commands.psm1:426 char:111
    + $newRelation = Set-WmiInstance -Class "SMS_CollectToSubCollect" -arguments $subArguments -computername <<<<
    $SccmServer.Machine -namespace $SccmServer.Namespace
    + CategoryInfo : InvalidData: (:) [Set-WmiInstance], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SetWmiInstance

    VERBOSE: Return the new collection with ID
    Add-SCCMCollectionRule : Cannot bind argument to parameter 'collectionID' because it is null.
    At C:\blah\createcollectionsforsites.ps1:6 char:73
    + $newqueryrule = Add-SCCMCollectionRule -Server $SccmServer -collectionID <<<< $newRoot.CollectionId -queryExpression
    "select * from SMS_R_System inner join SMS_G_System_SYSTEM_ENCLOSURE on SMS_G_System_SYSTEM_ENCLOSURE.ResourceId = S
    MS_R_System.ResourceId inner join SMS_G_System_COMPUTER_SYSTEM on SMS_G_System_COMPUTER_SYSTEM.ResourceId = SMS_R_Syste
    m.ResourceId where SMS_R_System.ADSiteName = "$adsite.site" and SMS_G_System_SYSTEM_ENCLOSURE.ChassisTypes in ("8","9",
    "10","11","12","14","18","21") and SMS_G_System_COMPUTER_SYSTEM.Manufacturer not like "%VMware%"" -queryRuleName "$adsi
    te.site" -limitToCollectionId "GL100A0B" -Verbose
    + CategoryInfo : InvalidData: (:) [Add-SCCMCollectionRule], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Add-SCCMCollectionRule

    Can anyone help me?

  35. yash

    Hi Riro,

    Have try to add functions provided here (copy those functions below to your script above provided)
    http://activedirectory.ncsu.edu/advanced-topics/scripting-center/permissions-add-on-for-sccm-powershell-module/
    but it is not working – while using command “New-SCCMInstancePermission ”
    ————————————————-
    $myserver = connect-sccmserver SCCM02
    $server = “SCCM02″
    New-SCCMInstancePermission -SccmServer $Server -InstanceID GAR0001D -InstancePermission 1 -ObjectKey 1 -UserName “DIR\sccm.delegation.power”
    ———————————————————–

    its giving me error :
    Cannot convert value “\\\:SMS_UserInstancePermissions” to type “System.Management.ManagementClass”. Error: “Invalid par
    ameter ”
    —————-
    Can you please assist me whats wrong here.

    Thanks

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>