CMPivot Reference

The following examples were compiled from the CMPivot Home screen examples and the PowerShell equivalent commands were extracted from the CMPivot PowerShell script that is copied down locally to C:\Windows\CCM\ScriptStore. The goal is the provide a way to understand what each command is actually doing when you run it.

Interpreting this Reference

  • Query Type

    • WMI - The command run locally on the client is querying WMI. Any entity not listed here but available in CMPivot uses the same WMI Class that ConfigMgr Client Hardware Inventory uses.
    • Powershell - These are special custom commands unique to CMPivot. The included PowerShell Equivalent example is taken directly from the local CMPivot script.
  • WMI (Namespace, Class)

    • The WMI Namespace and Class of the Entity where applicable. If not listed, then the entity uses custom PowerShell to query the data.
  • Local Query Name

    • This is the name that the local CMPivot script uses to query this entity.
  • Syntax

    • A Kusto Syntax of how to query the entity showing any parameter options.
  • Example

    • Shows how to query the Entity with examples of the parameter format where required.
  • PowerShell Equivalent

    • PowerShell example that can be used to validate that the data being queried is coming from a source you expect.

AadStatus

  • Query Type: Powershell

  • Local Query Name: AadStatus

  • Syntax:

    1
    
    AadStatus
    
  • Example:

    1
    
    AadStatus
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    $dsregcmd = "$Env:Windir\system32\dsregcmd.exe"
    $rawoutput = & $dsregcmd /status
    
    $hash = @{}
    
    foreach( $line in $rawoutput )
    {
        $sep = $line.IndexOf(":")
    
        if( $sep -ne -1 )
        {
            $propName = $line.SubString(0, $sep).Trim()
            $propValue = $line.SubString($sep+1).Trim()
    
            if( $propValue -eq 'YES' )
            {
                $propValue = $true
            }
            elseif( $propValue -eq 'NO' )
            {
                $propValue = $false
            }
    
            $hash.Add($propName,$propValue)
        }
    }
    
    if( $hash.Count -eq 0 ) 
    {
        throw 'dsregcmd returned invalid response'
    }
    
    $hash
    

Administrators

  • Query Type: Powershell

  • Local Query Name: Administrators

  • Syntax:

    1
    
    Administrators
    
  • Example:

    1
    
    Administrators
    
  • PowerShell Equivalent:

    1
    
    Get-LocalGroupMember -SID S-1-5-32-544
    

AppCrash

  • Query Type: Powershell

  • Local Query Name: AppCrash

  • Syntax:

    1
    
    AppCrash
    
  • Example:

    1
    
    AppCrash | summarize dcount( Device ) by FileName,Version
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    try {
        $crashes = Get-EventLog -LogName Application -After (Get-Date).AddDays(-7) -InstanceId 1000 -Source 'Application Error'
    
        $results = foreach ($crash in $crashes)  
        {
            $hash = @{
                    FileName = $crash.ReplacementStrings[0]
                    Version = $crash.ReplacementStrings[1]
                    ReportId = $crash.ReplacementStrings[12]
                    DateTime = $crash.TimeGenerated
            } 
        }
        $results       
    }
    catch{}
    

AutoStartSoftware

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2/sms, SMS_AutoStartSoftware)

  • Syntax:

    1
    
    AutoStartSoftware
    
  • Example:

    1
    
    AutoStartSoftware | summarize dcount( Device ) by Product
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2/sms -Class SMS_AutoStartSoftware
    

Bios

  • Query Type: Wmi

  • WMI (Namespace, Class): Win32_Bios

  • Syntax:

    1
    
    Bios
    
  • Example:

    1
    
    Bios | summarize dcount( Device ) by Manufacturer
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2 -Class Win32_Bios
    

CcmLog

  • Query Type: Powershell

  • Local Query Name: CCMlog

  • Syntax:

    1
    
    CcmLog(<logFileName>,[<timespan>])
    
  • Example:

    1
    
    CcmLog('Scripts', 1d)
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    
    $logFileName = 'Scripts'
    $secondsAgo = 86400
    
    $key = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64)
    $subKey =  $key.OpenSubKey("SOFTWARE\Microsoft\CCM\Logging\@Global")
    $ccmlogdir = $subKey.GetValue("LogDirectory")
    $key.Close()
    $logPath = (join-path $ccmlogdir ($logFileName+".log"))
    
    #verify format of file name
    if(( $logFileName -match '[\w\[email protected]]+' ) -and ([System.IO.File]::Exists($logPath)))
    {        
        $lines = (get-content -path $logpath -ErrorAction Stop)
    
        [regex]$ccmLog = '<!\[LOG\[(?<logtext>.*)\]LOG\]!><\s*time\s*\=\s*"(?<time>\d\d:\d\d:\d\d)[^"]+"\s+date\s*\=\s*"(?<date>[^"]+)"\s+component\s*\=\s*"(?<component>[^"]*)"\s+context\s*\=\s*"(?<context>[^"]*)"\s+type\s*\=\s*"(?<type>[^"]+)"\s+thread\s*\=\s*"(?<thread>[^"]+)"\s+file\s*\=\s*"(?<file>[^"]+)"\s*>'
    
        $results = for( $index = $lines.Length-1; $index -ge 0; $index-- )
        {
            $line = $lines[$index]
    
            $m = $ccmLog.Match($line)
    
            if( $m.Success -eq $true )
            {
                $hash = @{
                    LogText = $m.Groups["logtext"].Value
                    DateTime = ([DateTime]($m.Groups["date"].Value +' '+ $m.Groups["time"].Value)).ToUniversalTime()
                    Component = $m.Groups["component"].Value
                    Context = $m.Groups["context"].Value
                    Type = $m.Groups["type"].Value
                    Thread = $m.Groups["thread"].Value
                    File = $m.Groups["file"].Value
                }
    
                # Filter out logs based on timespan
                if ( [System.DateTime]::Compare($hash.DateTime, (Get-Date).AddSeconds(-1*$secondsAgo).ToUniversalTime()) -lt 0 )
                {
                    break
                }
                else
                {
                    $hash
                }
            }   
        }
    
        # Reverse the results list to ascending datetime
        $results.Reverse()
    }
    

Connection

  • Query Type: Powershell

  • Local Query Name: Connections

  • Syntax:

    1
    
    Connection
    
  • Example:

    1
    
    Connection
    
  • PowerShell Equivalent:

    1
    2
    3
    4
    5
    6
    7
    8
    
    $netstat = "$Env:Windir\system32\netstat.exe"
    $rawoutput = & $netstat -f
    $netstatdata = $rawoutput[3..$rawoutput.count] | ConvertFrom-String | select p2,p3,p4,p5 | where p5 -eq 'established' | select P4  
    
    foreach( $data in $netstatdata) {
        $data.P4.Substring(0,$data.P4.LastIndexOf(":"))
    }
    
    

Device

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2, Win32_ComputerSystem)

  • Syntax:

    1
    
    Device
    
  • Example:

    1
    
    Device
    

Disk

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2, Win32_LogicalDisk)

  • Syntax:

    1
    
    Disk
    
  • Example:

    1
    
    Disk | summarize dcount( Device ) by Description
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2 -Class Win32_LogicalDisk
    

EPStatus

  • WMI (Namespace, Class): EPStatus

  • Query Type: Powershell

  • Local Query Name: EPStatus

  • Syntax:

    1
    
    EPStatus
    
  • Example:

    1
    
    EPStatus
    
  • PowerShell Equivalent:

    1
    
    Get-MpComputerStatus
    

EventLog

  • Query Type: Powershell

  • Local Query Name: EventLog

  • Syntax:

    1
    
    EventLog(<logFileName>, [timespan])
    
  • Example:

    1
    
    EventLog('Security',1d)
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    $logName = 'Security'
    $secondsAgo = 86400
    
    $events = Get-EventLog -LogName $logName -After (Get-Date).AddSeconds(-1*$secondsAgo)
    
    $results = foreach ($event in $events)  
    {
        @{
            DateTime = $event.TimeGenerated
            EntryType = $event.EntryType
            Source = $event.Source
            EventID = $Event.EventID
            Message = $Event.Message
        } 
    }
    $results
    

File

  • Query Type: Powershell

  • Local Query Name: File

  • Syntax:

    1
    
    File(<filename>)
    
  • Example:

    1
    
    File('%windir%\\notepad.exe')
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    $fileSpec = [System.Environment]::ExpandEnvironmentVariables( '%windir%\notepad.exe' )
    
    $results = foreach( $file in (Get-Item -Force -ErrorAction SilentlyContinue -Path $filespec))
    {
        $fileSHA256 = ""
        $fileMD5 = ""
    
        try {
            $fileSHA256 = (get-filehash -ErrorAction SilentlyContinue -Path $file).Hash 
            $fileMD5 = (get-filehash -ErrorAction SilentlyContinue -Path $file -Algorithm MD5).Hash
        }
        catch {}
    
        @{
            FileName = $file.FullName
            Mode = $file.Mode
            LastWriteTime = $file.LastWriteTime
            Size = $file.Length
            Version = $file.VersionInfo.ProductVersion
            SHA256Hash = $fileSHA256
            MD5Hash = $fileMD5
        }
    }
    $results
    

FileContent

  • Query Type: Powershell

  • Local Query Name: FileContent

  • Syntax:

    1
    
    FileContent(<filename>)
    
  • Example:

    1
    
    FileContent('%windir%\\smscfg.ini')
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    $filepath = [System.Environment]::ExpandEnvironmentVariables( '%windir%\smscfg.ini' )
    
    if( [System.IO.File]::Exists($filepath) )
    {        
        $lines = (get-content -path $filepath -ErrorAction Stop)
    
        $results = for ($index = 0; $index -lt $lines.Length; $index++)
        {
            $line = $lines[$index]
            @{
                Line = $index+1
                Content = $line
            }
        }
        $results
    }
    

FileShare

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2, Win32_Share)

  • Syntax:

    1
    
    FileShare
    
  • Example:

    1
    
    FileShare | summarize dcount( Device ) by Name
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2 -Class Win32_Share
    

InstalledSoftware

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2/sms, SMS_InstalledSoftware)

  • Syntax:

    1
    
    InstalledSoftware
    
  • Example:

    1
    
    InstalledSoftware | summarize dcount( Device ) by ProductName
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2/sms -Class SMS_InstalledSoftware
    

IPConfig

  • Query Type: Powershell

  • Local Query Name: IPConfig

  • Syntax:

    1
    
    IPConfig
    
  • Example:

    1
    
    IPConfig
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    $ipconfigs = (Get-NetIPConfiguration -ErrorAction Stop)
    
    $results = foreach( $ipconfig in $ipconfigs )
    {
        @{
            InterfaceAlias = $ipconfig.InterfaceAlias
            Name = $ipconfig.NetProfile.Name
            InterfaceDescription = $ipconfig.InterfaceDescription
            Status = $ipconfig.NetAdapter.Status
            IPV4Address = $ipconfig.IPv4Address.IPAddress
            IPV6Address = $ipconfig.IPv6Address.IPAddress
            IPV4DefaultGateway = $ipconfig.IPv4DefaultGateway.NextHop
            IPV6DefaultGateway = $ipconfig.IPv6DefaultGateway.NextHop
            DNSServerList = ($ipconfig.DNSServer.ServerAddresses -join "; ")
        }
    }
    $results
    

OS

  • Query Type: Wmi

  • WMI (Namespace, Class): Win32_OperatingSystem

  • Syntax:

    1
    
    OS
    
  • Example:

    1
    
    OS
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2 -Class Win32_OperatingSystem
    

Process

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2, Win32_Process)

  • Syntax:

    1
    
    Process
    
  • Example:

    1
    
    Process | summarize dcount( Device ) by Name
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2 -Class Win32_Process
    

ProcessModule

  • Query Type: Powershell

  • Local Query Name: ProcessModule

  • Syntax:

    1
    
    ProcessModule(<processname>)
    
  • Example:

    1
    
    ProcessModule('explorer')"
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    $processName = 'explorer'
    
    $modules = Get-Process -name $processName -module -ErrorAction SilentlyContinue
    
    $results = foreach ($module in $modules)  
    {
        @{
            ModuleName = $module.ModuleName
            FileName = $module.FileName
            FileVersion = $module.FileVersion
            Size = $module.Size
            MD5Hash = (get-filehash -ErrorAction SilentlyContinue -Path $module.FileName -Algorithm MD5).Hash
        } 
    }
    $results
    

Registry

  • Query Type: Powershell

  • Local Query Name: registry

  • Syntax:

    1
    
    Registry(<registrypath>)
    
  • Example:

    1
    
    Registry('hklm:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion')
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    $regSpec = 'hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion'
    
    $result = New-Object System.Collections.Generic.List[Object]
    
    foreach( $regKey in (Get-Item -ErrorAction SilentlyContinue -Path $regSpec) )
    {
        foreach( $regValue in $regKey.Property )
        {
            $val = $regKey.GetValue($regValue)
    
            if( $val -ne $null)
            {
                if( $val.GetType() -eq [Byte[]] )
                {
                    $val = [System.BitConverter]::ToString($val)
                }
                elseif( $val.GetType() -eq [String[]] )
                {
                    $val = [System.String]::Join(", ", $val)
                }
    
                $hash = @{
                    Property = $regValue
                    Value = $val.ToString()
                }
            }
    
            $result.Add($hash)
        }
    }
    $result
    

RegistryKey

  • Query Type: Powershell

  • Local Query Name: registrykey

  • Syntax:

    1
    
    RegistryKey(<registrypath>)
    
  • Example:

    1
    
    RegistryKey('hklm:\\SOFTWARE\\Microsoft\\*')
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    $regSpec = 'hklm:\SOFTWARE\Microsoft\*'
    
    $result = New-Object System.Collections.Generic.List[Object]
    
    foreach( $regKey in (Get-Item -ErrorAction SilentlyContinue -Path $regSpec) )
    {
        foreach( $regValue in $regKey.Property )
        {
            $val = $regKey.GetValue($regValue)
    
            if( $val -ne $null)
            {
                if( $val.GetType() -eq [Byte[]] )
                {
                    $val = [System.BitConverter]::ToString($val)
                }
                elseif( $val.GetType() -eq [String[]] )
                {
                    $val = [System.String]::Join(", ", $val)
                }
    
                $hash = @{
                    Property = $regValue
                    Value = $val.ToString()
                }
            }
    
            $result.Add($hash)
        }
    }
    $result
    

Service

  • Query Type: Wmi

  • WMI (Namespace, Class): (ROOT/cimv2, Win32_Service)

  • Syntax:

    1
    
    Service
    
  • Example:

    1
    
    Service | summarize dcount( Device ) by Name
    
  • PowerShell Equivalent:

    1
    
    Get-WMIObject -Namespace ROOT/cimv2 -Class Win32_Service
    

SMBConfig

  • Query Type: Powershell

  • Local Query Name: SMBConfig

  • Syntax:

    1
    
    SMBConfig
    
  • Example:

    1
    
    SMBConfig
    
  • PowerShell Equivalent:

    1
    
    Get-SmbServerConfiguration
    

SoftwareUpdate

  • Query Type: Powershell

  • Local Query Name: Updates

  • Syntax:

    1
    
    SoftwareUpdate
    
  • Example:

    1
    
    SoftwareUpdate
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    
    $Session =  [activator]::CreateInstance([type]::GetTypeFromProgID("Microsoft.Update.Session",$null))
    $Searcher = $Session.CreateUpdateSearcher()
    $Searcher.ServerSelection = 0
    
    $MissingUpdates = $Searcher.Search("DeploymentAction=* and IsInstalled=0 and Type='Software'")  
    
    if ($MissingUpdates.Updates.Count -gt 0) 
    {
        $results = foreach( $Update in $MissingUpdates.Updates )
        {   
            $KBArticleIDs = ""
            foreach( $KB in $Update.KBArticleIDs)
            {
                if( $KBAticleIDs.Length -gt 0 )
                {
                    $KBArticleIDs = $KBArticleIDs + ","
                }
    
                $KBArticleIDs = $KBArticleIDs + "KB$KB"
            }
    
            $SecurityBulletinIDs = ""
            foreach( $BulletinID in $Update.SecurityBulletinIDs)
            {
                if( $SecurityBulletinIDs.Length -gt 0 )
                {
                    $SecurityBulletinIDs = $SecurityBulletinIDs + ","
                }
    
                $SecurityBulletinIDs = $SecurityBulletinIDs + $BulletinID
            }
    
            $Categories = ""
            foreach( $Category in $Update.Categories)
            {
                if( $Categories.Length -gt 0 )
                {
                    $Categories = $Categories + ","
                }
    
                $Categories = $Categories + $Category.Name
            }
    
            @{                 
                Title = $Update.Title
                RebootRequired = $Update.RebootRequired
                LastDeploymentChangeTime = $Update.LastDeploymentChangeTime
                UpdateID = $Update.Identity.UpdateID
                KBArticleIDs = $KBArticleIDs
                SecurityBulletinIDs = $SecurityBulletinIDs                                
                Categories = $Categories                
            }
        }
        $results
    } 
    

User

  • Query Type: Powershell

  • Local Query Name: Users

  • Syntax:

    1
    
    User
    
  • Example:

    1
    
    User | summarize dcount( Device ) by UserName
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    $users = New-Object System.Collections.Generic.List[String]
    
    foreach( $user in (get-WmiObject -class Win32_LoggedOnUser -ErrorAction Stop | Select Antecedent))
    {
        $parts = $user.Antecedent.Split("""")
    
        if(( $parts[1] -ne "Window Manager" ) -and (($parts[1] -ne $env:COMPUTERNAME) -or (($parts[3] -notlike "UMFD-*")) -and ($parts[3] -notlike "DWM-*")))
        {
            $users.Add($parts[1] + "\" + $parts[3])            
        }
    }
    
    $users | sort-object -Unique
    

WinEvent

  • Query Type: Powershell

  • Local Query Name: winevent

  • Syntax:

    1
    
    WinEvent(<logfilename>, [<timespan>])
    
  • Example:

    1
    
    WinEvent('Application', 1d)
    
  • PowerShell Equivalent:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    $logFileName =  'Application'
    $secondsAgo = 86400
    
    $ComputerName = [System.Environment]::MachineName 
    $EventStartDate = (Get-Date).AddSeconds(-1*$secondsAgo)
    $EventEndTime = (Get-Date)
    $filterTable = @{logname = $logFileName; StartTime=$EventStartDate; EndTime=$EventEndTime}
    
    # Filter out the winEvent logs that we need
    try {
        $winEvents = Get-WinEvent -ComputerName $ComputerName -FilterHashTable $filterTable  -ErrorAction Stop
    }
    catch {}
    
    $results = foreach ($winEvent in $winEvents)  
    {
        @{
            DateTime = $winEvent.TimeCreated
            LevelDisplayName = $winEvent.LevelDisplayName
            ProviderName = $winEvent.ProviderName
            ID = $winEvent.ID
            Message = $winEvent.Message
        } 
    }
    $results