#-------------------------------------------------------------------------------
# localized performance counters for 2008R2 and later
#-------------------------------------------------------------------------------
# Returns 2 letters LanguageName (and full for china)
function Get-CultureLanguage()
{
$cul = Get-UICulture
if ($cul.TwoLetterISOLanguageName -eq 'zh') {
return $cul.Name
}
return $cul.TwoLetterISOLanguageName;
}
# 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-RegLocalizedPerfCounterNames($computerName = $env:COMPUTERNAME)
{
$path = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage"
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computerName)
$sub = $Reg.OpenSubKey($path)
if ($sub-eq $null) {
$Reg.Close()
return $null
}
$val= $sub.GetValue('Counter')
if ($rv -eq 0)
{
return $Buffer.ToString().Substring(0, $BufferSize-1)
}
else
{
Throw 'Get-PdhLookupPerfNameByIndex : Unable to retrieve localized name for performance counter ID ({0}) on computer "{1}".' -f $ID, $ComputerName
}
}
# inner function for localized non-exchange counters.
# Usage:
# arrayCounters = result of Get-RegLocalizedPerfCounterNames
# [object/counter]Conf = @(ID,'EnglishName')
# parameters = @(objectConf,CounterConf)
# Returns Get-Counter Result
# P.S...
function Get-LocalizedPerfCounter([hashtable]$arrayCounters, [String] $format, [array]$paramters)
{
$cul = Get-UICulture
#English language
if( $($cul.LCID -band 0xff) -ne 0x09)
{
#try to get locolized values
if ( $arrayCounters -ne $null)
{
#from regestry
for($i=0; $i -lt $paramters.Count; $i++)
{
[UInt32] $id = [UInt32]$paramters[$i][0]
if ($arrayCounters.ContainsKey($id) -eq $true)
{
$paramters[$i][1] = $arrayCounters[$id]
}
else
{
Throw 'Get-PerfCounter : Unable to retrieve localized name. (Index : {0} Name : {1})' -f $id,$paramters[$i][1]
}
}
}
else
{
#win32 api
for($i=0; $i -lt $paramters.Count; $i++)
{
[UInt32] $id = [UInt32]$paramters[$i][0]
$paramters[$i][1] = Get-PdhLookupPerfNameByIndex $id
}
}
}
#get counter
$counter = $format -f $paramters[0][1], $paramters[1][1]
return (Get-Counter -ComputerName $computerName -ErrorAction SilentlyContinue ($counter))
}
# wrapper for Get-LocalizedPerfCounter for multi instance counters
# Usage:
# arrayCounters = result of Get-RegLocalizedPerfCounterNames
# objectName = @(Id,'English Name')
# counterName = @(Id,'English Name')
# instances - string template for instances
# returns hashtable dic['instanceName']=value
function Get-MultiInstancePerfCounter ([hashtable]$arrayCounters, [array]$objectName,[array]$counterName,[string]$instances) {
$samples = (Get-LocalizedPerfCounter $arrayCounters $("\{0}($instances)\{1}") $($objectName, $counterName)).CounterSamples;
$resultSet = @{}
foreach ($sample in $samples) {
if ($sample.Path -match "\\\\.+\\.+\((.+)\)\\") {
$resultSet.Add($Matches[1],$sample.CookedValue)
}
}
return $resultSet
}
# wrapper for Get-LocalizedPerfCounter for single instance counters
# Usage:
# arrayCounters = result of Get-RegLocalizedPerfCounterNames
# objectName = @(Id,'English Name')
# counterName = @(Id,'English Name')
# returns CookedValue
function Get-SingleInstancePerfCounter ($arrayCounters, $objectName,$counterName) {
return (Get-LocalizedPerfCounter $arrayCounters ("\{0}\{1}") $($objectName, $counterName)).CounterSamples.CookedValue;
}
# Build dictionary for exchange coutners in form
# dic['objectName']['counterName'] = foreign counterName
# dic['objectName']['objectName'] = foreign objectName
function Get-ExchangeLocalizedPerfCounterNames ($computerName = $env:COMPUTERNAME) {
$lang = Get-CultureLanguage
$ht = Get-LocalizationHashTable
return $ht[$lang]
}
# Gets Exchange performance counters in localized way
# Usage: if counter is multiinstance returns hashtable dic['instanceName']=value
# if counter is singleinstance returns just value
function Get-ExchangePerfCounter ($objectName,$counterName,$instanceName = $null) {
$ht = $exchangeLocalizedCounterNames
$locObjectName=$objectName
$locCounterName = $counterName
if ($ht -ne $null -and $ht.ContainsKey($objectName)) {
$htCounter = $ht[$objectName]
if ($htCounter.ContainsKey($objectName)) {
$locObjectName = $htCounter[$objectName]
}
if ($htCounter.ContainsKey($counterName)) {
$locCounterName = $htCounter[$counterName]
}
}
if ($instanceName -eq $null) {
$value = Get-Counter -ComputerName $computerName "\$locObjectName\$locCounterName" -ErrorAction SilentlyContinue
return $value.CounterSamples.CookedValue
} else {
$samples = (Get-Counter -ComputerName $computerName "\$locObjectName($instanceName)\$locCounterName" -ErrorAction SilentlyContinue).CounterSamples;
$resultSet = @{}
foreach ($sample in $samples) {
if ($sample.Path -match "\\\\.+\\.+\((.+)\)\\") {
$resultSet.Add($Matches[1],$sample.CookedValue)
}
}
return $resultSet
}
}
#Creates SCOM Property Bag for performance instance. if value is null. recored is skipped
function createBag($objectName,$counterName,$instanceName,$value,$misc=@{}) {
if ($value -eq $null) {
LogEvent $INFORMATION_EVENT_TYPE "No Value for Property Bag ObjectName: $objectName CounterName: $counterName InstanceName: $instanceName" 2
return
}
$bag = $api.CreatePropertyBag()
$bag.AddValue('ObjectName',$objectName)
$bag.AddValue('CounterName',$counterName)
$bag.AddValue('InstanceName',$instanceName)
$bag.AddValue('Value',$value)
foreach ($prop in $misc.GetEnumerator()) {
$prop.AddValue($prop.Key,$prop.Value)
}
$Script:scriptBagCount++
if($script:returnPropertyBagToPipeline)
{
$bag
LogEvent $INFORMATION_EVENT_TYPE "New Property Bag (via pipeline) ObjectName: $objectName CounterName: $counterName InstanceName: $instanceName Value: $value" 2
}
else
{
$api.AddItem($bag)
LogEvent $INFORMATION_EVENT_TYPE "New Property Bag (via AddItem) ObjectName: $objectName CounterName: $counterName InstanceName: $instanceName Value: $value" 2
}
}
# Creates scom property bag by counter configuration for single InstanceName.
# Usage:
# configuration hashtable: @{ObjectName,CounterName,InstanceName}
# $pc - counter configuration in system
# $sc - counter configuration for counter in SCOM
# $misc - additional data for property bag @{Name=Value}
function SingleExchangeCounter([hashtable]$pc,[hashtable]$sc,[hashtable]$misc=@{}) {
$value = Get-ExchangePerfCounter $pc.ObjectName $pc.CounterName $pc.InstanceName
if ($pc.InstanceName -ne $null) {
$value = $value[$pc.InstanceName]
}
createBag $sc.ObjectName $sc.CounterName $sc.InstanceName $value $misc
}
# MultiInstance version of SingleExchangeCounter
function MultiExchangeCounter($pc,$sc,$misc=@{}) {
$values = Get-ExchangePerfCounter $pc.ObjectName $pc.CounterName $pc.InstanceName
foreach ($value in $values.GetEnumerator()){
createBag $sc.ObjectName $sc.CounterName $value.Key $value.Value $misc
}
}
# Creates entry in EventLog if current Debug_mode >= level
function LogEvent($eventType, $message,[int]$level=1)
{
if ($DEBUG_MODE -ge $level)
{
$api.LogScriptEvent($DEBUG_MODULE, $SCRIPT_EVENT_ID, $eventType, $message);
}
}
# Gets a volume (inc. mnt point) name, id, capacity, freespace and caption by folder name
Function GetFolderVolume($path) {
GWMI Win32_Volume -ComputerName $computerName | ?{ $path -like "$($_.Name)*" } | sort Name -Descending | select -First 1 Name, DeviceId, Caption, Capacity, FreeSpace
}