I had a lot of software at a costumer which needed to be uninstalled automatically because of expensive licencing. I stumbled upon this article from systemcenterdudes where Nicolas Pilon have created queries and collections in SCCM containing exactly what i needed. Based on that article i created a powershell script to do that for me.
Define which metered files to define collections from
To limit the script not to create collections for every metered file, I choose to “tag” a metered file by typing “Licensed” in the description field. The Name field has to be the name from ARP/Appwiz.cpl as the field will be used for the collection query by the script.
See an example here of a tagged metered file:
If the ARP name of an appliccation has an variable to the name simply use a wildcard as show below on Visual Studio:
The script
The script have some variables that can be suited to your needs. The script will create the device collection folder that you have defined in $CollectionDevFolderName
Variables:
[code language="powershell"] #Variables $DriveName = "SCCMSite" $DeviceLimitingCollection = "All Systems" $CollectionDevFolderName = "Query Rules\Software\Software Meetering" $CollectionDevFolderPath = $DriveName + ":" + "\DeviceCollection\$CollectionDevFolderName" $SoftwareMeteringCommentTrigger = "Licensed" $NumberOfDaysSinceUse = 120 [/code]
Running the script on the site server will create the examples as shown:
Outcome
Here is the collections created. Running the script again will skip the creation of existing collections.
Complete code
<#
.SYNOPSIS
.DESCRIPTION
.PARAMETER
.EXAMPLE
.NOTES
Author: Morten Rnborg
Date: 10-09-2018
Last Updated: 03-02-2019
https://mroenborg.com
#>
################################################
function Random-StartTime
{
[string]$RandomHour = (Get-Random -Maximum 23)
[string]$RandomMinute = (Get-Random -Maximum 59)
[string]$RandomStartTime = $RandomHour + ":" + $RandomMinute
return $RandomStartTime
}
#Get the sitecode
Get-WMIObject -Namespace "root\SMS" -Class "SMS_ProviderLocation" | foreach-object{if ($_.ProviderForLocalSite -eq $true){$SiteCode=$_.SiteCode}}
#Import module
Import-Module(Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)
#Variables
$DeviceLimitingCollection = "All Systems"
$CollectionDevFolderName = "Query Rules\Software\Software Meetering"
$CollectionDevFolderPath = $SiteCode + ":" + "\DeviceCollection\$CollectionDevFolderName"
$SoftwareMeteringCommentTrigger = "Licensed"
$NumberOfDaysSinceUse = 120
#Set location
Set-Location($SiteCode + ":") -ErrorAction Stop
Write-Host "***********************************************START SCRIPT***********************************************"
Write-Host "Running in the context of '$($env:USERNAME)'"
#Check if the collection folder exist
if (!(Test-Path $CollectionDevFolderPath))
{
#Variables
$Folders = $CollectionDevFolderPath.Split("\")
$FolderPath = $null
#Check each folder for existence
Foreach($Folder in $Folders){
#Define this folder path
$FolderPath += ( $Folder + "\")
#If not there, create it
if(!(Test-Path $FolderPath.TrimEnd("\"))){
Write-Host ("Device collection folder `"$FolderPath`" not existing, creating it..")
New-Item $FolderPath
}
}
}
#All metering rules Get-CMSoftwareInventory
$ManagedMeteringRules = Get-CMSoftwareMeteringRule | Where-Object {$_.Comment -eq $SoftwareMeteringCommentTrigger}
Foreach($Rule in $ManagedMeteringRules){
#Variables
$Schedule = New-CMSchedule -Start (Random-StartTime) -RecurInterval Days -RecurCount 1
$FileName = ($Rule.FileName)
$ProductName = ($Rule.ProductName)
$InstalledCollName = ("$ProductName | Installed")
$LastUseLastXDaysCollName = ("$ProductName | Used in the last $NumberOfDaysSinceUse days")
$WarningZoneCollName = ("$ProductName | Not used in the last $NumberOfDaysSinceUse days")
$InstalledQuery = "SELECT SMS_R_SYSTEM.ResourceID, SMS_R_SYSTEM.ResourceType, SMS_R_SYSTEM.Name, SMS_R_SYSTEM.SMSUniqueIdentifier, SMS_R_SYSTEM.ResourceDomainORWorkgroup, SMS_R_SYSTEM.Client from SMS_R_System inner join SMS_G_System_INSTALLED_SOFTWARE on SMS_G_System_INSTALLED_SOFTWARE.ResourceId = SMS_R_System.ResourceId where SMS_G_System_INSTALLED_SOFTWARE.ProductName like `"$ProductName`""
$LastUsageInLastXDaysQuery = "SELECT SMS_R_SYSTEM.ResourceID, SMS_R_SYSTEM.ResourceType, SMS_R_SYSTEM.Name, SMS_R_SYSTEM.SMSUniqueIdentifier, SMS_R_SYSTEM.ResourceDomainORWorkgroup, SMS_R_SYSTEM.Client from SMS_R_SYSTEM inner join SMS_MonthlyUsageSummary on SMS_R_SYSTEM.ResourceID = SMS_MonthlyUsageSummary.ResourceID INNER JOIN SMS_MeteredFiles ON SMS_MonthlyUsageSummary.FileID = SMS_MeteredFile.MeteredFileID WHERE SMS_MeteredFiles.FileName = `"$FileName`" AND DateDiff(day, SMS_MonthlyUsageSummary.LastUsage, GetDate()) < $NumberOfDaysSinceUse"
$CollectionDescription = "Auto created"
#Create the colleciton containing the devices having the softwre installed
if($Collection = Get-CMDeviceCollection -Name $InstalledCollName){
#The collection already exist
Write-Host "Device collection '$InstalledCollName', already exist"
}else{
#Create the collection
try {
Write-Host "Creating device collection '$InstalledCollName' and query"
$InstallCollection = New-CMDeviceCollection -Name $InstalledCollName -LimitingCollectionName $DeviceLimitingCollection -RefreshType Periodic -RefreshSchedule $Schedule -Comment $CollectionDescription
Add-CMDeviceCollectionQueryMembershipRule -Collection $InstallCollection -QueryExpression $InstalledQuery -RuleName "Using '$ProductName' productname"
Move-CMObject -FolderPath $CollectionDevFolderPath -InputObject $InstallCollection
}
catch {
Write-Host ("$_")
}
}
#Create the collection containing users of the software within the last X days
if($Collection = Get-CMDeviceCollection -Name $LastUseLastXDaysCollName){
#The collection already exist
Write-Host "Device collection '$LastUseLastXDaysCollName', already exist"
}else{
#Create the collection
try {
Write-Host "Creating device collection '$LastUseLastXDaysCollName' and query"
$LastUseXCollection = New-CMDeviceCollection -Name $LastUseLastXDaysCollName -LimitingCollectionName $InstalledCollName -RefreshType Periodic -RefreshSchedule $Schedule -Comment $CollectionDescription
Add-CMDeviceCollectionQueryMembershipRule -Collection $LastUseXCollection -QueryExpression $LastUsageInLastXDaysQuery -RuleName "Using $FileName"
Move-CMObject -FolderPath $CollectionDevFolderPath -InputObject $LastUseXCollection
}
catch {
Write-Host ("$_")
}
}
#Create the collection containing users who have not used it in the last X days
if($Collection = Get-CMDeviceCollection -Name $WarningZoneCollName){
#The collection already exist
Write-Host "Device collection '$WarningZoneCollName', already exist"
}else{
#Create the collection
try {
Write-Host "Creating device collection '$WarningZoneCollName' including colls"
$Collection = New-CMDeviceCollection -Name $WarningZoneCollName -LimitingCollectionName $InstalledCollName -RefreshType Periodic -RefreshSchedule $Schedule -Comment $CollectionDescription
Add-CMDeviceCollectionIncludeMembershipRule -Collection $Collection -IncludeCollectionName $InstalledCollName
Add-CMDeviceCollectionExcludeMembershipRule -Collection $Collection -ExcludeCollectionName $LastUseLastXDaysCollName
Move-CMObject -FolderPath $CollectionDevFolderPath -InputObject $Collection
}
catch {
Write-Host ("$_")
}
}
}
Ou Acheter Du Cialis Forum Prix Du Kamagra Pfizer Cialis Prezzo 5 Mg viagra prescription Walgreens Propecia Review Buy Zithromax Online Next Day Delivery Cephalexin For Skin Rash
Hi nice,
this tool keep you to easy create SCCM collection based an AD OU
https://github.com/dakhama-mehdi/Easy-OU-TO-SCCM