Changelog
-
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
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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-User "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'"
2010-03-26 13:08
[...] SCCM PoSH [...]
2010-05-17 15:31
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.
2010-05-26 06:17
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…
Then search for the object with Get-SCCMComputer and add it to the collection with Add-SCCMCollectionRule
2010-06-21 23:10
[...] PowerShell installed, and it does require PowerShell v2. We used the SCCM PowerShell module located here, which appears to be the most “complete” unofficial PowerShell module I’ve found [...]
2010-08-24 22:50
Thank you very much for great module !!!
Shouldn’t line 262 be …
2010-08-31 06:29
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!
2010-08-31 07:57
Hi Pete… actually I have been in contact with Greg Ramsey ( http://myitforum.com/cs2/blogs/gramsey/default.aspx ) about codeplex.
After the last MMS Greg posted a huge update to this project: http://configmgrcx.codeplex.com/
2010-09-06 14:56
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…
Regards
Rico
2010-09-06 15:29
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…
2010-09-13 11:52
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
I get the following error
can you help me?
2010-09-13 12:03
Hi Luigi.
Looks like a small typo/miss in your powershell code, try this instead:
(Define the object $myserver as a SCCM-connection, then use it when you create the direct rule)
2010-09-13 14:06
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
2010-09-13 14:30
You can use Add-SCCMCollectionRule to add a direct membership. Use the “name” param to specify a computername.
2010-09-13 14:47
this is the script I used
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
2010-09-13 16:41
I did it!
I’ve used the following script
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
2010-09-13 17:22
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:
(Add -Verbose to Add-SCCMCollectionRule to get some more info on what the script does)
2010-09-13 17:41
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”
2010-09-13 18:10
Luigi… I had to admit it, you found a bug.
Did fix it and the module is updated, so give it another go. (Works fine in my dev-environment)
2010-09-14 09:55
thanks for all your support. I will try it later and give you feedback
2010-09-27 13:02
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
2010-10-29 08:30
[...] SCCM PoSH [...]
2010-11-22 04:03
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??
2010-11-22 07:44
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)
2010-11-22 13:30
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
2011-06-01 04:50
[...] SCCM-Commands PowerShell module [...]
2011-09-15 04:40
[...] the aid of PoSh extensions, the solution gets much easier if we leverage community resources. At https://snowland.se/sccm-posh/ you’ll find community-authored PowerShell extensions that allow for the quick creation of [...]