Last active
March 12, 2018 23:45
-
-
Save Jaykul/8de83bb3ff299999be84 to your computer and use it in GitHub Desktop.
LocalizeCounterNames
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$Processor, $Privileged = Get-CounterLocalizedName "Processor", "% Privileged Time" | |
Get-Counter "\$Processor(_Total)\$Privileged" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add-Type -Name PerfCounter -Namespace Win32 -MemberDefinition ' | |
[DllImport("pdh.dll", SetLastError=true, CharSet=CharSet.Unicode)] | |
public static extern UInt32 PdhLookupPerfNameByIndex( | |
string szMachineName, uint dwNameIndex, | |
System.Text.StringBuilder szNameBuffer, ref uint pcchNameBufferSize); | |
[DllImport("pdh.dll", SetLastError=true, CharSet=CharSet.Unicode)] | |
public static extern UInt32 PdhExpandCounterPath( | |
string szWildCardPath, | |
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] | |
char[] mszExpandedPathList, ref uint pcchPathListLength); | |
[DllImport("pdh.dll", SetLastError=true, CharSet=CharSet.Unicode)] | |
public static extern UInt32 PdhLookupPerfIndexByName( | |
string szMachineName, | |
string szNameBuffer, | |
ref uint dwNameIndex | |
); | |
' | |
# Build a hash array of offsets into the counter buffer. Use the index | |
# values from the performance data queries to access the offsets. | |
function Get-CounterLocalizedName { | |
#.Synopsis | |
# Look up localized names for performance counters. | |
#.Description | |
# Users Remote Registry and PDH* functions to look up counters on remote computers | |
#.Example | |
# $Processor, $Privileged = Get-CounterLocalizedName "Processor", "% Privileged Time" | |
# Get-Counter "\$Processor(_Total)\$Privileged" | |
# | |
# Shows how to get counters in a culture-sensitive way. | |
param( | |
# The counter name to look up | |
[string[]]$Counter, | |
# The name of a computer to query against | |
[Alias("CN")] | |
$ComputerName = $env:COMPUTERNAME | |
) | |
if(!$global:LocalizedCounters) { | |
$global:LocalizedCounters = @{} | |
} | |
if(!$global:LocalizedCounters.ContainsKey($ComputerName)) { | |
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("PerformanceData", $ComputerName) # , "Registry32" | |
$Counters = $Reg.GetValue('Counter') | |
$Reg.Close() | |
#return registry values | |
$global:LocalizedCounters.$ComputerName = @{} | |
$global:LocalizedCounters.($ComputerName).ByIndex = @{} | |
$global:LocalizedCounters.($ComputerName).ByName = @{} | |
foreach($c in $Counters) | |
{ | |
if($foreach.MoveNext()) { | |
$global:LocalizedCounters.($ComputerName).ByName.($foreach.Current) = $c | |
} | |
} | |
} | |
foreach($c in $Counter) { | |
$index = $global:LocalizedCounters.($ComputerName).ByName.($c) | |
if(!$global:LocalizedCounters.($ComputerName).ByIndex.ContainsKey($index)) { | |
$global:LocalizedCounters.($ComputerName).ByIndex.$Index = Invoke-PdhLookupPerfNameByIndex $Index $ComputerName | |
} | |
$global:LocalizedCounters.($ComputerName).ByIndex.$Index | |
} | |
} | |
set-alias Get-PerfName Invoke-PdhLookupPerfNameByIndex | |
set-alias gpn Invoke-PdhLookupPerfNameByIndex | |
function Invoke-PdhLookupPerfNameByIndex { | |
param( | |
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] | |
[int]$Index, | |
[Alias("CN")] | |
$ComputerName = $env:COMPUTERNAME | |
) | |
process { | |
[UInt32]$BufferSize = 0 | |
$Buffer = New-Object System.Text.StringBuilder $BufferSize | |
$ErrorCode = "{0:X}" -f [Win32.PerfCounter]::PdhLookupPerfNameByIndex($ComputerName, $Index, $Buffer, [Ref]$BufferSize) | |
if("800007D2" -eq $ErrorCode <# PDH_MORE_DATA #>) { | |
$Buffer = New-Object System.Text.StringBuilder $BufferSize | |
$ErrorCode = "{0:X}" -f [Win32.PerfCounter]::PdhLookupPerfNameByIndex($ComputerName, $Index, $Buffer, [Ref]$BufferSize) | |
} | |
if ($ErrorCode -eq "0") | |
{ | |
$Buffer.ToString() | |
} | |
else | |
{ | |
Write-Error ("ERRORCODE ${ErrorCode}: Unable to retrieve localized name!" + | |
"`nYou may look up the error code here https://msdn.microsoft.com/en-us/library/windows/desktop/aa373046" | |
) | |
} | |
} | |
} | |
set-alias Get-PerfIndex Invoke-PdhLookupPerfNameByIndex | |
set-alias gpi Invoke-PdhLookupPerfNameByIndex | |
function Invoke-PdhLookupPerfIndexByName { | |
param( | |
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] | |
[string]$Name, | |
[Alias("CN")] | |
$ComputerName = $env:COMPUTERNAME | |
) | |
process { | |
[UInt32]$Index = 0 | |
$ErrorCode = "{0:X}" -f [Win32.PerfCounter]::PdhLookupPerfIndexByName($ComputerName, $Name, [Ref]$Index) | |
if ($ErrorCode -eq "0") | |
{ | |
$Index | |
} elseif($ErrorCode -eq "C0000BD4"){ | |
Write-Error "ERRORCODE ${ErrorCode}: Unable to find the specified string ($Name) in the list of performance counter names and help-text strings" | |
} elseif($ErrorCode -eq "800007D0"){ | |
Write-Error "ERRORCODE ${ErrorCode}: Unable to connect to the specified computer ($ComputerName), perhaps the computer is offline." | |
} | |
else | |
{ | |
Write-Error ("ERRORCODE ${ErrorCode}: Unable to retrieve index!" + | |
"`nYou may look up the error code here https://msdn.microsoft.com/en-us/library/windows/desktop/aa373046" | |
) | |
} | |
} | |
} | |
function Invoke-PdhExpandCounterPath { | |
param($Path) | |
[UInt32]$BufferSize = 0 | |
$Buffer = [char[]]"" | |
$ErrorCode = "{0:X}" -f [Win32.PerfCounter]::PdhExpandCounterPath($Path, $Buffer, [Ref]$BufferSize) | |
if("800007D2" -eq $ErrorCode <# PDH_MORE_DATA #>) { | |
$Buffer = New-Object "char[]" $BufferSize | |
$ErrorCode = "{0:X}" -f [Win32.PerfCounter]::PdhExpandCounterPath($Path, $Buffer, [Ref]$BufferSize) | |
} | |
if("0" -eq $ErrorCode) { | |
(New-Object String $Buffer).Trim(([char]0)) -split ([char]0) | |
} | |
else | |
{ | |
# TODO: possibly handle the error codes and print the real error message | |
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa373046%28v=vs.85%29.aspx | |
Write-Error (("ERRORCODE ${ErrorCode}: Unable to expand path." )+ | |
" Please verify you passed a path like \\ComputerName\CounterPath*\Name" + | |
"`nYou may look up the error code here https://msdn.microsoft.com/en-us/library/windows/desktop/aa373046" | |
) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment