Monday, January 13, 2014

PowerShell script to list SCCM 2012 collections that take long time to evaluate

Needed to list collections that were having evaluation delay issues. To do so, I put together a small script parsing Colleval log files & listing problematic collections. You might want to have a look at their queries & try to optimize them.
# created by Michael Sedenkov January 13, 2014
# Script listing SCCM 2012 Collections that are taking too long to be evaluated

$inputLogFiles = @("\\SCCM2012Server\logs$\colleval.lo_", "\\SCCM2012Server\logs$\colleval.log")
$evaluationTimeLimit = 60
$outputFile = "c:\temp\CollectionsRefreshDelay.csv"
$SCCMconnection = "\\SCCM2012Server\root\sms\site_SCCM2012Site"

write-Output "CollectionID;CollName;EvalDelaySeconds;Time" | Out-File $OutPutFile
write-host "CollectionID;CollName;EvalDelaySeconds;Time";
foreach ($file in $inputLogFiles) {
 cat $file |
  Select-String "PF: [Primary Evaluator] successfully evaluated collection" -SimpleMatch |
   select -expand line |
    foreach {
   #write-host $_
   $_ -match "PF: \[Primary Evaluator\] successfully evaluated collection \[(\w+)\] and used (\d+\.\d+) seconds  \$\$<(.{19})" | out-null
   if ([int]$matches[2] -ge $evaluationTimeLimit) {
    $ConnectionString = $SCCMconnection + ":SMS_Collection.CollectionID='" + $matches[1] +"'"
    $Coll = [wmi]$ConnectionString
    write-host $matches[1]"; " $Coll.Name"; " $matches[2]"; " $matches[3]
    write-Output "$($matches[1]);$($Coll.Name);$($matches[2]);$($matches[3])" | Out-File $OutPutFile -append
   }  
  }
 }

Sunday, January 12, 2014

PowerShell script to inventory SCCM 2012 collections

I was looking for a simple way to inventory hundreds of SCCM 2012 collections we are having & compile all interesting information, like
  • Collection ID (WMI: CollectionID)
  • Name (Name)
  • Refresh Type (RefreshType)
  • Refresh schedule (RefreshSchedule.DaySpan, RefreshSchedule.HourSpan)
  • Number of members (MemberCount)
  • Limiting Collection Name (LimitToCollectionName)
  • Limiting Collection ID (LimitToCollectionID)
  • Number of Membership Rules (CollectionRules.Count)
  • Exact Membership Rules (CollectionRules.RuleName, CollectionRules.IncludeCollectionID, CollectionRules.ExcludeCollectionID, CollectionRules.ResourceID, CollectionRules.QueryExpression)
The script below creates a CSV file (with ';' as a divider), containing a header + all information concerning SCCM 2012 collections.

SCCMCollectionsInformationExport.ps1
# created by Michael Sedenkov January 10, 2014
# Script listing SCCM 2012 Collections and their properties

# CSV file, where are we are going to export
$OutPutFile = "c:\temp\Collections.csv"
# name of SCCM 2012 server where are we connecting
$SCCMServerName = "CM01"
# name of SCCM 2012 namespace, containing SCCM Site Name
$SCCMNameSpace = "root\sms\site_XXX"

write-Output "CollectionID;CollName;RefreshType;Days;Hours;MemberCount;LimitingCollection;LimitingCollectionID;NumberOfCollectionRules;RuleName1;Rule1;RuleName2;Rule2;RuleName3;Rule3;RuleName4;Rule4" | Out-File $OutPutFile
gwmi sms_collection -computer $SCCMServerName -namespace $SCCMNameSpace | foreach {
  $Coll = [wmi] $_.__Path
  $CollRulesString = ""
  if ($Coll.CollectionRules.Count) {
 # in case some collection rules are really defined
 $CollRuleCount = $Coll.CollectionRules.Count
 foreach ($CollRule in $Coll.CollectionRules) {
  #write-host "Collection Rule Name: " $CollRule.RuleName
  $CollRulesString = $CollRulesString + $CollRule.RuleName + "; "
  if ($CollRule.IncludeCollectionID) {
   #write-host "Included collection: " $CollRule.IncludeCollectionID
   $CollRulesString = $CollRulesString + "IncludedCollID " + $CollRule.IncludeCollectionID + "; "
  }
  if ($CollRule.ExcludeCollectionID) {
   #write-host "Excluded collection: " $CollRule.ExcludeCollectionID
   $CollRulesString = $CollRulesString + "ExcludedCollID " + $CollRule.ExcludeCollectionID + "; "
  }
  if ($CollRule.ResourceID) {
   #write-host "Direct membership: " $CollRule.ResourceID
   $CollRulesString = $CollRulesString + "MachineID " + $CollRule.ResourceID + "; "
  }
  if ($CollRule.QueryExpression) {
   #write-host "Collection query: " $CollRule.QueryExpression
   $CollRulesString = $CollRulesString + "Query " + $CollRule.QueryExpression + "; "
  }
 }
  }
  # if no rules are present
  else { $CollRuleCount = 0 }
  # convert RefreshType values into descriptions
  $CollRefreshT = ""
  switch ($Coll.RefreshType) {
 1 {$CollRefreshT = "Manual"}
 2 {$CollRefreshT = "Schedule"}
 4 {$CollRefreshT = "Incremental"}
 6 {$CollRefreshT = "Schedule+Incremental"}
  }
  write-host $Coll.CollectionID "; " $Coll.Name "; " $CollRefreshT "; " $Coll.RefreshSchedule.DaySpan "; " $Coll.RefreshSchedule.HourSpan "; " $Coll.MemberCount "; " $Coll.LimitToCollectionName "; " $Coll.LimitToCollectionID "; " $CollRuleCount "; " $CollRulesString #$Coll.CollectionRules[0].RuleName
  Write-Output "$($Coll.CollectionID);$($Coll.Name);$($CollRefreshT);$($Coll.RefreshSchedule.DaySpan);$($Coll.RefreshSchedule.HourSpan);$($Coll.MemberCount);$($Coll.LimitToCollectionName);$($Coll.LimitToCollectionID);$($CollRuleCount);$($CollRulesString)" | Out-File $OutPutFile -Append
}