mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 04:36:39 +00:00
Copy files for Microsoft.PowerShell.Commands.Diagnostics [SD:714215]
Commit 2e2daeaff52930d981a31e0030d7161c4b45cc48
This commit is contained in:
1 parent
61ea879f73
commit
4e4a07c5e8
12 files changed
+6631
No files matched your search
@@ -0,0 +1,122 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands.Diagnostics.Common
|
||||||
|
{
|
||||||
|
|
||||||
|
internal class CommonUtilities
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// No-op private ctor to prevent the default ctor from getting generated.
|
||||||
|
// This class is intended to only have static members.
|
||||||
|
//
|
||||||
|
private CommonUtilities() {␍}
|
||||||
|
|
||||||
|
//
|
||||||
|
// StringArrayToString helper converts a string array into a comma-separated string.
|
||||||
|
// Note this has only limited use, individual strings cannot have commas.
|
||||||
|
//
|
||||||
|
public static string StringArrayToString (IEnumerable input)
|
||||||
|
{
|
||||||
|
string ret = "";
|
||||||
|
foreach (string element in input)
|
||||||
|
{
|
||||||
|
ret += element + ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ret.TrimEnd();
|
||||||
|
ret = ret.TrimEnd(',');
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
|
||||||
|
const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
|
||||||
|
const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
|
||||||
|
const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
|
||||||
|
const uint FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
private static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
|
||||||
|
uint dwMessageId, uint dwLanguageId,
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
StringBuilder lpBuffer,
|
||||||
|
uint nSize, IntPtr Arguments);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
private static extern IntPtr LoadLibraryEx(
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
|
||||||
|
IntPtr hFile,
|
||||||
|
uint dwFlags
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll")]
|
||||||
|
private static extern bool FreeLibrary(IntPtr hModule);
|
||||||
|
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", EntryPoint = "GetUserDefaultLangID", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||||
|
private static extern ushort GetUserDefaultLangID();
|
||||||
|
|
||||||
|
|
||||||
|
public static uint FormatMessageFromModule(uint lastError, string moduleName, out String msg)
|
||||||
|
{
|
||||||
|
Debug.Assert (!string.IsNullOrEmpty(moduleName));
|
||||||
|
|
||||||
|
uint formatError = 0;
|
||||||
|
msg = String.Empty;
|
||||||
|
IntPtr moduleHandle = IntPtr.Zero;
|
||||||
|
|
||||||
|
moduleHandle = LoadLibraryEx(moduleName, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
|
if (moduleHandle == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return (uint)Marshal.GetLastWin32Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
uint dwFormatFlags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE;
|
||||||
|
uint LANGID = (uint)GetUserDefaultLangID();
|
||||||
|
uint langError = (uint)Marshal.GetLastWin32Error();
|
||||||
|
if (langError != 0)
|
||||||
|
{
|
||||||
|
LANGID = 0; // neutral
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder outStringBuilder = new StringBuilder(1024);
|
||||||
|
uint nChars = FormatMessage(dwFormatFlags,
|
||||||
|
moduleHandle,
|
||||||
|
lastError,
|
||||||
|
LANGID,
|
||||||
|
outStringBuilder,
|
||||||
|
(uint)outStringBuilder.Capacity,
|
||||||
|
IntPtr.Zero);
|
||||||
|
|
||||||
|
if (nChars == 0)
|
||||||
|
{
|
||||||
|
formatError = (uint)Marshal.GetLastWin32Error();
|
||||||
|
//Console.WriteLine("Win32FormatMessage", String.Format(null, "Error formatting message: {0}", formatError));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg = outStringBuilder.ToString();
|
||||||
|
if (msg.EndsWith(Environment.NewLine, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
msg = msg.Substring(0, msg.Length - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
FreeLibrary(moduleHandle);
|
||||||
|
}
|
||||||
|
return formatError;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands.GetCounter
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class CounterFileInfo
|
||||||
|
{
|
||||||
|
internal CounterFileInfo(DateTime oldestRecord,
|
||||||
|
DateTime newestRecord,
|
||||||
|
UInt32 sampleCount)
|
||||||
|
{
|
||||||
|
|
||||||
|
_oldestRecord = oldestRecord;
|
||||||
|
_newestRecord = newestRecord;
|
||||||
|
_sampleCount = sampleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CounterFileInfo(){}
|
||||||
|
|
||||||
|
public DateTime OldestRecord
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _oldestRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private DateTime _oldestRecord = DateTime.MinValue;
|
||||||
|
|
||||||
|
public DateTime NewestRecord
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _newestRecord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private DateTime _newestRecord = DateTime.MaxValue;
|
||||||
|
|
||||||
|
public UInt32 SampleCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _sampleCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private UInt32 _sampleCount = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Resources;
|
||||||
|
using Microsoft.Powershell.Commands.GetCounter.PdhNative;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands.GetCounter
|
||||||
|
{
|
||||||
|
|
||||||
|
public class PerformanceCounterSample
|
||||||
|
{
|
||||||
|
internal PerformanceCounterSample()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal PerformanceCounterSample(string path,
|
||||||
|
string instanceName,
|
||||||
|
double cookedValue,
|
||||||
|
UInt64 rawValue,
|
||||||
|
UInt64 secondValue,
|
||||||
|
uint multiCount,
|
||||||
|
PerformanceCounterType counterType,
|
||||||
|
UInt32 defaultScale,
|
||||||
|
UInt64 timeBase,
|
||||||
|
DateTime timeStamp,
|
||||||
|
UInt64 timeStamp100nSec,
|
||||||
|
UInt32 status)
|
||||||
|
{
|
||||||
|
_path = path;
|
||||||
|
_instanceName = instanceName;
|
||||||
|
_cookedValue = cookedValue;
|
||||||
|
_rawValue = rawValue;
|
||||||
|
_secondValue = secondValue;
|
||||||
|
_multiCount = multiCount;
|
||||||
|
_counterType = counterType;
|
||||||
|
_defaultScale = defaultScale;
|
||||||
|
_timeBase = timeBase;
|
||||||
|
_timeStamp = timeStamp;
|
||||||
|
_timeStamp100nSec = timeStamp100nSec;
|
||||||
|
_status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Path
|
||||||
|
{
|
||||||
|
get {return _path;}
|
||||||
|
set {_path = value;}
|
||||||
|
}
|
||||||
|
private string _path = "";
|
||||||
|
|
||||||
|
|
||||||
|
public string InstanceName
|
||||||
|
{
|
||||||
|
get {return _instanceName;}
|
||||||
|
set {_instanceName = value;}
|
||||||
|
}
|
||||||
|
private string _instanceName = "";
|
||||||
|
|
||||||
|
|
||||||
|
public double CookedValue
|
||||||
|
{
|
||||||
|
get {return _cookedValue;}
|
||||||
|
set {_cookedValue = value;}
|
||||||
|
}
|
||||||
|
private double _cookedValue = 0;
|
||||||
|
|
||||||
|
public UInt64 RawValue
|
||||||
|
{
|
||||||
|
get {return _rawValue;}
|
||||||
|
set {_rawValue = value;}
|
||||||
|
}
|
||||||
|
private UInt64 _rawValue = 0;
|
||||||
|
|
||||||
|
public UInt64 SecondValue
|
||||||
|
{
|
||||||
|
get {return _secondValue;}
|
||||||
|
set {_secondValue = value;}
|
||||||
|
}
|
||||||
|
private UInt64 _secondValue = 0;
|
||||||
|
|
||||||
|
public uint MultipleCount
|
||||||
|
{
|
||||||
|
get {return _multiCount;}
|
||||||
|
set {_multiCount = value;}
|
||||||
|
}
|
||||||
|
private uint _multiCount = 0;
|
||||||
|
|
||||||
|
public PerformanceCounterType CounterType
|
||||||
|
{
|
||||||
|
get {return _counterType;}
|
||||||
|
set {_counterType = value;}
|
||||||
|
}
|
||||||
|
private PerformanceCounterType _counterType = 0;
|
||||||
|
|
||||||
|
public DateTime Timestamp
|
||||||
|
{
|
||||||
|
get {return _timeStamp;}
|
||||||
|
set {_timeStamp = value;}
|
||||||
|
}
|
||||||
|
private DateTime _timeStamp = DateTime.MinValue;
|
||||||
|
|
||||||
|
|
||||||
|
public UInt64 Timestamp100NSec
|
||||||
|
{
|
||||||
|
get {return _timeStamp100nSec;}
|
||||||
|
set {_timeStamp100nSec = value;}
|
||||||
|
}
|
||||||
|
private UInt64 _timeStamp100nSec = 0;
|
||||||
|
|
||||||
|
public UInt32 Status
|
||||||
|
{
|
||||||
|
get {return _status;}
|
||||||
|
set {_status = value;}
|
||||||
|
}
|
||||||
|
private UInt32 _status = 0;
|
||||||
|
|
||||||
|
public UInt32 DefaultScale
|
||||||
|
{
|
||||||
|
get {return _defaultScale;}
|
||||||
|
set {_defaultScale = value;}
|
||||||
|
}
|
||||||
|
private UInt32 _defaultScale = 0;
|
||||||
|
|
||||||
|
public UInt64 TimeBase
|
||||||
|
{
|
||||||
|
get {return _timeBase;}
|
||||||
|
set {_timeBase = value;}
|
||||||
|
}
|
||||||
|
private UInt64 _timeBase = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PerformanceCounterSampleSet
|
||||||
|
{
|
||||||
|
internal PerformanceCounterSampleSet()
|
||||||
|
{
|
||||||
|
_resourceMgr = new ResourceManager("GetEventResources", Assembly.GetExecutingAssembly());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal PerformanceCounterSampleSet (DateTime timeStamp,
|
||||||
|
PerformanceCounterSample[] counterSamples,
|
||||||
|
bool firstSet) : this()
|
||||||
|
{
|
||||||
|
_timeStamp = timeStamp;
|
||||||
|
_counterSamples = counterSamples;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime Timestamp
|
||||||
|
{
|
||||||
|
get {return _timeStamp;}
|
||||||
|
set {_timeStamp = value;}
|
||||||
|
}
|
||||||
|
private DateTime _timeStamp = DateTime.MinValue;
|
||||||
|
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample.CounterSamples",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public PerformanceCounterSample[] CounterSamples
|
||||||
|
{
|
||||||
|
get {return _counterSamples;}
|
||||||
|
set {_counterSamples = value;}
|
||||||
|
}
|
||||||
|
private PerformanceCounterSample[] _counterSamples = null;
|
||||||
|
|
||||||
|
private ResourceManager _resourceMgr = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands.GetCounter
|
||||||
|
{
|
||||||
|
|
||||||
|
public class CounterSet
|
||||||
|
{
|
||||||
|
internal CounterSet(string setName,
|
||||||
|
string machineName,
|
||||||
|
PerformanceCounterCategoryType categoryType,
|
||||||
|
string setHelp,
|
||||||
|
ref Dictionary<string, string[]> counterInstanceMapping)
|
||||||
|
{
|
||||||
|
_counterSetName = setName;
|
||||||
|
if (machineName == null || machineName.Length == 0)
|
||||||
|
{
|
||||||
|
machineName = ".";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_machineName = machineName;
|
||||||
|
if (!_machineName.StartsWith(@"\\", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
_machineName = @"\\" + _machineName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_counterSetType = categoryType;
|
||||||
|
_description = setHelp;
|
||||||
|
_counterInstanceMapping = counterInstanceMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CounterSetName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _counterSetName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string _counterSetName = "";
|
||||||
|
|
||||||
|
public string MachineName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _machineName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string _machineName = ".";
|
||||||
|
|
||||||
|
public PerformanceCounterCategoryType CounterSetType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _counterSetType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private PerformanceCounterCategoryType _counterSetType;
|
||||||
|
|
||||||
|
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string _description = "";
|
||||||
|
|
||||||
|
internal Dictionary<string, string[]> CounterInstanceMapping
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _counterInstanceMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Dictionary<string, string[]> _counterInstanceMapping;
|
||||||
|
|
||||||
|
public StringCollection Paths
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
StringCollection retColl = new StringCollection();
|
||||||
|
foreach (string counterName in this.CounterInstanceMapping.Keys)
|
||||||
|
{
|
||||||
|
string path;
|
||||||
|
if (CounterInstanceMapping[counterName].Length != 0)
|
||||||
|
{
|
||||||
|
path = (_machineName == ".") ?
|
||||||
|
("\\" + _counterSetName + "(*)\\" + counterName) :
|
||||||
|
(_machineName + "\\" + _counterSetName + "(*)\\" + counterName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = (_machineName == ".") ?
|
||||||
|
("\\" + _counterSetName + "\\" + counterName) :
|
||||||
|
(_machineName + "\\" + _counterSetName + "\\" + counterName);
|
||||||
|
}
|
||||||
|
retColl.Add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retColl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringCollection PathsWithInstances
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
StringCollection retColl = new StringCollection();
|
||||||
|
foreach (string counterName in CounterInstanceMapping.Keys)
|
||||||
|
{
|
||||||
|
foreach (string instanceName in CounterInstanceMapping[counterName])
|
||||||
|
{
|
||||||
|
string path = (_machineName == ".") ?
|
||||||
|
("\\" + _counterSetName + "(" + instanceName + ")\\" + counterName) :
|
||||||
|
(_machineName + "\\" + _counterSetName + "(" + instanceName + ")\\" + counterName);
|
||||||
|
retColl.Add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retColl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Net;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Microsoft.Powershell.Commands.GetCounter.PdhNative;
|
||||||
|
using Microsoft.PowerShell.Commands.GetCounter;
|
||||||
|
using Microsoft.PowerShell.Commands.Diagnostics.Common;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands
|
||||||
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Class that implements the Get-Counter cmdlet.
|
||||||
|
///
|
||||||
|
[Cmdlet("Export", "Counter", DefaultParameterSetName = "ExportCounterSet", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=138337")]
|
||||||
|
public sealed class ExportCounterCommand : PSCmdlet
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Path parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = true,
|
||||||
|
Position = 0,
|
||||||
|
ValueFromPipelineByPropertyName = true,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[Alias("PSPath")]
|
||||||
|
|
||||||
|
public string Path
|
||||||
|
{
|
||||||
|
get {return _path;}
|
||||||
|
set {_path = value;}
|
||||||
|
}
|
||||||
|
private string _path;
|
||||||
|
private string _resolvedPath;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Format parameter.
|
||||||
|
// Valid strings are "blg", "csv", "tsv" (case-insensitive).
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = false,
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[ValidateNotNull]
|
||||||
|
public string FileFormat
|
||||||
|
{
|
||||||
|
get {return _format;}
|
||||||
|
set {_format = value;}
|
||||||
|
}
|
||||||
|
private string _format = "BLG";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MaxSize parameter
|
||||||
|
// Maximum output file size, in megabytes.
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
public UInt32 MaxSize
|
||||||
|
{
|
||||||
|
get {return _maxSize;}
|
||||||
|
set {_maxSize = value;}
|
||||||
|
}
|
||||||
|
private UInt32 _maxSize = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// InputObject parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = true,
|
||||||
|
ValueFromPipeline = true,
|
||||||
|
ValueFromPipelineByPropertyName = true,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.ExportCounterCommand.InputObject",
|
||||||
|
Justification="A PerformanceCounterSampleSet[] is required here because Powershell supports arrays natively.")]
|
||||||
|
public PerformanceCounterSampleSet[] InputObject
|
||||||
|
{
|
||||||
|
get {return _counterSampleSets;}
|
||||||
|
set {_counterSampleSets = value;}
|
||||||
|
}
|
||||||
|
private PerformanceCounterSampleSet[] _counterSampleSets = new PerformanceCounterSampleSet[0];
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Force switch
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
public SwitchParameter Force
|
||||||
|
{
|
||||||
|
get {return _force;}
|
||||||
|
set{_force = value;}
|
||||||
|
}
|
||||||
|
private SwitchParameter _force;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Circular switch
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
public SwitchParameter Circular
|
||||||
|
{
|
||||||
|
get {return _circular;}
|
||||||
|
set{_circular = value;}
|
||||||
|
}
|
||||||
|
private SwitchParameter _circular;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ResourceManager _resourceMgr = null;
|
||||||
|
|
||||||
|
private PdhHelper _pdhHelper = null;
|
||||||
|
|
||||||
|
private bool _stopping = false;
|
||||||
|
|
||||||
|
private bool _queryInitialized = false;
|
||||||
|
|
||||||
|
private PdhLogFileType _outputFormat = PdhLogFileType.PDH_LOG_TYPE_BINARY;
|
||||||
|
|
||||||
|
//
|
||||||
|
// BeginProcessing() is invoked once per pipeline
|
||||||
|
//
|
||||||
|
protected override void BeginProcessing()
|
||||||
|
{
|
||||||
|
|
||||||
|
_resourceMgr = new ResourceManager("GetEventResources", Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine the OS version: this cmdlet requires Windows 7
|
||||||
|
// because it uses new Pdh functionality.
|
||||||
|
//
|
||||||
|
if (System.Environment.OSVersion.Version.Major < 6 ||
|
||||||
|
(System.Environment.OSVersion.Version.Major == 6 && System.Environment.OSVersion.Version.Minor < 1))
|
||||||
|
{
|
||||||
|
string msg = _resourceMgr.GetString("ExportCtrWin7Required");
|
||||||
|
Exception exc = new Exception(msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "ExportCtrWin7Required", ErrorCategory.NotImplemented, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate the Format and CounterSamples arguments
|
||||||
|
//
|
||||||
|
ValidateFormat();
|
||||||
|
|
||||||
|
if (Circular.IsPresent && _maxSize == 0)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterCircularNoMaxSize"));
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterCircularNoMaxSize", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint res = _pdhHelper.ConnectToDataSource();
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = _pdhHelper.OpenQuery();
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// EndProcessing() is invoked once per pipeline
|
||||||
|
//
|
||||||
|
protected override void EndProcessing()
|
||||||
|
{
|
||||||
|
_pdhHelper.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Handle Control-C
|
||||||
|
///
|
||||||
|
protected override void StopProcessing()
|
||||||
|
{
|
||||||
|
_stopping = true;
|
||||||
|
_pdhHelper.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessRecord() override.
|
||||||
|
// This is the main entry point for the cmdlet.
|
||||||
|
// When counter data comes from the pipeline, this gets invoked for each pipelined object.
|
||||||
|
// When it's passed in as an argument, ProcessRecord() is called once for the entire _counterSampleSets array.
|
||||||
|
//
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
Debug.Assert(_counterSampleSets.Length != 0 && _counterSampleSets[0] != null);
|
||||||
|
|
||||||
|
ResolvePath();
|
||||||
|
|
||||||
|
uint res = 0;
|
||||||
|
|
||||||
|
if (!_queryInitialized)
|
||||||
|
{
|
||||||
|
if (_format.ToLower(CultureInfo.InvariantCulture).Equals("blg"))
|
||||||
|
{
|
||||||
|
res = _pdhHelper.AddRelogCounters(_counterSampleSets[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = _pdhHelper.AddRelogCountersPreservingPaths(_counterSampleSets[0]);
|
||||||
|
}
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = _pdhHelper.OpenLogForWriting(_resolvedPath, _outputFormat, Force.IsPresent, _maxSize * 1024 * 1024, Circular.IsPresent, null);
|
||||||
|
if (res == PdhResults.PDH_FILE_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterFileExists"), _resolvedPath);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterFileExists", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
else if (res == PdhResults.PDH_LOG_FILE_CREATE_ERROR)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("FileCreateFailed"), _resolvedPath);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "FileCreateFailed", ErrorCategory.InvalidResult, null));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (res == PdhResults.PDH_LOG_FILE_OPEN_ERROR)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("FileOpenFailed"), _resolvedPath);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "FileOpenFailed", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
else if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_queryInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (PerformanceCounterSampleSet set in _counterSampleSets)
|
||||||
|
{
|
||||||
|
_pdhHelper.ResetRelogValues();
|
||||||
|
|
||||||
|
foreach (PerformanceCounterSample sample in set.CounterSamples)
|
||||||
|
{
|
||||||
|
bool bUnknownKey = false;
|
||||||
|
res = _pdhHelper.SetCounterValue(sample, out bUnknownKey);
|
||||||
|
if (bUnknownKey)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterExportSampleNotInInitialSet"), sample.Path, _resolvedPath);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterExportSampleNotInInitialSet", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
else if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
res = _pdhHelper.WriteRelogSample(set.Timestamp);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_stopping)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateFormat() helper.
|
||||||
|
// Validates Format argument: only "BLG", "TSV" and "CSV" are valid strings (case-insensitive)
|
||||||
|
//
|
||||||
|
private void ValidateFormat()
|
||||||
|
{
|
||||||
|
switch (_format.ToLower(CultureInfo.InvariantCulture))
|
||||||
|
{
|
||||||
|
case "blg":
|
||||||
|
_outputFormat = PdhLogFileType.PDH_LOG_TYPE_BINARY;
|
||||||
|
break;
|
||||||
|
case "csv":
|
||||||
|
_outputFormat = PdhLogFileType.PDH_LOG_TYPE_CSV;
|
||||||
|
break;
|
||||||
|
case "tsv":
|
||||||
|
_outputFormat = PdhLogFileType.PDH_LOG_TYPE_TSV;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterInvalidFormat"), _format);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterInvalidFormat", ErrorCategory.InvalidArgument, null));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResolvePath()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Collection<PathInfo> result = null;
|
||||||
|
result = SessionState.Path.GetResolvedPSPathFromPSPath(_path);
|
||||||
|
if (result.Count > 1)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("ExportDestPathAmbiguous"), _path);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "ExportDestPathAmbiguous", ErrorCategory.InvalidArgument, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PathInfo currentPath in result)
|
||||||
|
{
|
||||||
|
_resolvedPath = currentPath.ProviderPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ItemNotFoundException pathNotFound)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// This is an expected condition - we will be creating a new file
|
||||||
|
//
|
||||||
|
_resolvedPath = pathNotFound.ItemName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReportPdhError(uint res, bool bTerminate)
|
||||||
|
{
|
||||||
|
string msg;
|
||||||
|
uint formatRes = CommonUtilities.FormatMessageFromModule(res, "pdh.dll", out msg);
|
||||||
|
if (formatRes != 0)
|
||||||
|
{
|
||||||
|
msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterApiError"), res);
|
||||||
|
}
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
if (bTerminate)
|
||||||
|
{
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,645 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Net;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Microsoft.Powershell.Commands.GetCounter.PdhNative;
|
||||||
|
using Microsoft.PowerShell.Commands.GetCounter;
|
||||||
|
using Microsoft.PowerShell.Commands.Diagnostics.Common;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands
|
||||||
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Class that implements the Get-Counter cmdlet.
|
||||||
|
///
|
||||||
|
[Cmdlet(VerbsCommon.Get, "Counter", DefaultParameterSetName = "GetCounterSet", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=138335")]
|
||||||
|
public sealed class GetCounterCommand : PSCmdlet
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// ListSet parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Position = 0,
|
||||||
|
Mandatory = true,
|
||||||
|
ParameterSetName="ListSetSet",
|
||||||
|
ValueFromPipeline = true,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[AllowEmptyCollection]
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
|
||||||
|
public string[] ListSet
|
||||||
|
{
|
||||||
|
get {return _listSet;}
|
||||||
|
set {_listSet = value;}
|
||||||
|
}
|
||||||
|
private string[] _listSet = {"*"};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Counter parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Position = 0,
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
ValueFromPipeline = true,
|
||||||
|
ValueFromPipelineByPropertyName = true,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[AllowEmptyCollection]
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public string[] Counter
|
||||||
|
{
|
||||||
|
get {return _counter;}
|
||||||
|
set {_counter = value;
|
||||||
|
_defaultCounters = false;}
|
||||||
|
}
|
||||||
|
private string[] _counter = {@"\network interface(*)\bytes total/sec",
|
||||||
|
@"\processor(_total)\% processor time",
|
||||||
|
@"\memory\% committed bytes in use",
|
||||||
|
@"\memory\cache faults/sec",
|
||||||
|
@"\physicaldisk(_total)\% disk time",
|
||||||
|
@"\physicaldisk(_total)\current disk queue length"};
|
||||||
|
private bool _defaultCounters = true;
|
||||||
|
|
||||||
|
private List<string> _accumulatedCounters = new List<string>();
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// SampleInterval parameter.
|
||||||
|
// Defaults to 1 second.
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[ValidateRange((int)1, int.MaxValue)]
|
||||||
|
public int SampleInterval
|
||||||
|
{
|
||||||
|
get {return _sampleInterval;}
|
||||||
|
set {_sampleInterval = value;}
|
||||||
|
}
|
||||||
|
private int _sampleInterval = 1;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MaxSamples parameter
|
||||||
|
//
|
||||||
|
private const Int64 KEEP_ON_SAMPLING = -1;
|
||||||
|
[Parameter(
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[ValidateRange((Int64)1, Int64.MaxValue)]
|
||||||
|
public Int64 MaxSamples
|
||||||
|
{
|
||||||
|
get {return _maxSamples;}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_maxSamples = value;
|
||||||
|
_maxSamplesSpecified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Int64 _maxSamples = 1;
|
||||||
|
private bool _maxSamplesSpecified = false;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Continuous switch
|
||||||
|
//
|
||||||
|
[Parameter(ParameterSetName="GetCounterSet")]
|
||||||
|
public SwitchParameter Continuous
|
||||||
|
{
|
||||||
|
get {return _continuous;}
|
||||||
|
set{_continuous = value;}
|
||||||
|
}
|
||||||
|
private bool _continuous = false;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ComputerName parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources",
|
||||||
|
HelpMessageResourceId = "ComputerNameParamHelp")]
|
||||||
|
[ValidateNotNull]
|
||||||
|
[AllowEmptyCollection]
|
||||||
|
[Alias("Cn")]
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ComputerName",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public string[] ComputerName
|
||||||
|
{
|
||||||
|
get {return _computerName;}
|
||||||
|
set {_computerName = value;}
|
||||||
|
}
|
||||||
|
private string[] _computerName = new string[0];
|
||||||
|
|
||||||
|
private ResourceManager _resourceMgr = null;
|
||||||
|
|
||||||
|
private PdhHelper _pdhHelper = null;
|
||||||
|
|
||||||
|
private EventWaitHandle _cancelEventArrived = new EventWaitHandle(false, EventResetMode.ManualReset);
|
||||||
|
|
||||||
|
// Culture identifier(s)
|
||||||
|
private const int FrenchCultureId = 0x040C;
|
||||||
|
// The localized Pdh resource strings might use Unicode characters that are different from
|
||||||
|
// what the user can type with the keyboard to represent a special character.
|
||||||
|
//
|
||||||
|
// e.g. the apostrophe in Frence UI culture: it's [char]39 from keyboard, but it's [char]8217
|
||||||
|
// in the resource strings.
|
||||||
|
//
|
||||||
|
// With this dictionary, we can add special mapping if we find other special cases in the future.
|
||||||
|
private readonly Dictionary<int, List<Tuple<char, char>>> _cultureAndSpecialCharacterMap =
|
||||||
|
new Dictionary<int, List<Tuple<char, char>>>()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
FrenchCultureId, new List<Tuple<char, char>>()
|
||||||
|
{
|
||||||
|
// 'APOSTROPHE' to 'RIGHT SINGLE QUOTATION MARK'
|
||||||
|
new Tuple<char, char>((char) 0x0027, (char) 0x2019),
|
||||||
|
// 'MODIFIER LETTER APOSTROPHE' to 'RIGHT SINGLE QUOTATION MARK'
|
||||||
|
new Tuple<char, char>((char) 0x02BC, (char) 0x2019),
|
||||||
|
// 'HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT' to 'RIGHT SINGLE QUOTATION MARK'
|
||||||
|
new Tuple<char, char>((char) 0x275C, (char) 0x2019),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// BeginProcessing() is invoked once per pipeline
|
||||||
|
//
|
||||||
|
protected override void BeginProcessing()
|
||||||
|
{
|
||||||
|
_resourceMgr = new ResourceManager("GetEventResources", Assembly.GetExecutingAssembly());
|
||||||
|
|
||||||
|
_pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);
|
||||||
|
uint res = _pdhHelper.ConnectToDataSource();
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Continuous.IsPresent && _maxSamplesSpecified)
|
||||||
|
{
|
||||||
|
Exception exc = new Exception(string.Format(CultureInfo.CurrentCulture, _resourceMgr.GetString("CounterContinuousOrMaxSamples")));
|
||||||
|
ThrowTerminatingError (new ErrorRecord(exc, "CounterContinuousOrMaxSamples", ErrorCategory.InvalidArgument, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// EndProcessing() is invoked once per pipeline
|
||||||
|
//
|
||||||
|
protected override void EndProcessing()
|
||||||
|
{
|
||||||
|
if (ParameterSetName == "GetCounterSet")
|
||||||
|
{
|
||||||
|
ProcessGetCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
_pdhHelper.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle Control-C
|
||||||
|
//
|
||||||
|
protected override void StopProcessing()
|
||||||
|
{
|
||||||
|
_cancelEventArrived.Set();
|
||||||
|
_pdhHelper.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessRecord() override.
|
||||||
|
// This is the main entry point for the cmdlet.
|
||||||
|
//
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (ParameterSetName)
|
||||||
|
{
|
||||||
|
case "ListSetSet":
|
||||||
|
ProcessListSet();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "GetCounterSet":
|
||||||
|
AccumulatePipelineCounters();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "Invalid parameter set name: {0}", ParameterSetName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// AccumulatePipelineCounters() accumulates counter paths in the pipeline scenario:
|
||||||
|
// we do not want to start sampling until all the counters are supplied.
|
||||||
|
//
|
||||||
|
private void AccumulatePipelineCounters()
|
||||||
|
{
|
||||||
|
_accumulatedCounters.AddRange(_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessListSet() does the work to process ListSet parameter set.
|
||||||
|
//
|
||||||
|
private void ProcessListSet()
|
||||||
|
{
|
||||||
|
if (_computerName.Length == 0)
|
||||||
|
{
|
||||||
|
ProcessListSetPerMachine(null);
|
||||||
|
}
|
||||||
|
else foreach (string machine in _computerName)
|
||||||
|
{
|
||||||
|
ProcessListSetPerMachine(machine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessListSetPerMachine() helper lists counter sets on a machine.
|
||||||
|
// NOTE: machine argument should be NULL for the local machine
|
||||||
|
//
|
||||||
|
private void ProcessListSetPerMachine(string machine)
|
||||||
|
{
|
||||||
|
StringCollection counterSets = new StringCollection();
|
||||||
|
uint res = _pdhHelper.EnumObjects(machine, ref counterSets);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
//add an error message
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("NoCounterSetsOnComputer"), machine, res);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "NoCounterSetsOnComputer", ErrorCategory.InvalidResult, machine));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
|
||||||
|
List<Tuple<char, char>> characterReplacementList = null;
|
||||||
|
StringCollection validPaths = new StringCollection();
|
||||||
|
|
||||||
|
_cultureAndSpecialCharacterMap.TryGetValue(culture.LCID, out characterReplacementList);
|
||||||
|
|
||||||
|
foreach (string pattern in _listSet)
|
||||||
|
{
|
||||||
|
bool bMatched = false;
|
||||||
|
string normalizedPattern = pattern;
|
||||||
|
|
||||||
|
if (characterReplacementList != null)
|
||||||
|
{
|
||||||
|
foreach (Tuple<char, char> pair in characterReplacementList)
|
||||||
|
{
|
||||||
|
normalizedPattern = normalizedPattern.Replace(pair.Item1, pair.Item2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WildcardPattern wildLogPattern = new WildcardPattern(normalizedPattern, WildcardOptions.IgnoreCase);
|
||||||
|
|
||||||
|
foreach (string counterSet in counterSets)
|
||||||
|
{
|
||||||
|
if (!wildLogPattern.IsMatch(counterSet))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringCollection counterSetCounters = new StringCollection();
|
||||||
|
StringCollection counterSetInstances = new StringCollection();
|
||||||
|
|
||||||
|
res = _pdhHelper.EnumObjectItems(machine, counterSet, ref counterSetCounters, ref counterSetInstances);
|
||||||
|
if (res == PdhResults.PDH_ACCESS_DENIED)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterSetEnumAccessDenied"), counterSet);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterSetEnumAccessDenied", ErrorCategory.InvalidResult, null));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] instanceArray = new string[counterSetInstances.Count];
|
||||||
|
int i = 0;
|
||||||
|
foreach (string instance in counterSetInstances)
|
||||||
|
{
|
||||||
|
instanceArray[i++] = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Special case: no instances present: change to * to create a valid paths
|
||||||
|
//
|
||||||
|
if (instanceArray.Length == 1 &&
|
||||||
|
instanceArray[0].Length == 0)
|
||||||
|
{
|
||||||
|
instanceArray[0] = "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, string[]> counterInstanceMapping = new Dictionary<string, string[]>();
|
||||||
|
foreach (string counter in counterSetCounters)
|
||||||
|
{
|
||||||
|
if (!counterInstanceMapping.ContainsKey(counter))
|
||||||
|
{
|
||||||
|
counterInstanceMapping.Add(counter, instanceArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceCounterCategoryType categoryType = PerformanceCounterCategoryType.Unknown;
|
||||||
|
if (counterSetInstances.Count > 1)
|
||||||
|
{
|
||||||
|
categoryType = PerformanceCounterCategoryType.MultiInstance;
|
||||||
|
}
|
||||||
|
else //if (counterSetInstances.Count == 1) //???
|
||||||
|
{
|
||||||
|
categoryType = PerformanceCounterCategoryType.SingleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
string setHelp = _pdhHelper.GetCounterSetHelp(machine, counterSet);
|
||||||
|
|
||||||
|
CounterSet setObj = new CounterSet(counterSet, machine, categoryType, setHelp, ref counterInstanceMapping);
|
||||||
|
WriteObject (setObj);
|
||||||
|
bMatched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bMatched)
|
||||||
|
{
|
||||||
|
string msg = _resourceMgr.GetString("NoMatchingCounterSetsFound");
|
||||||
|
Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg,
|
||||||
|
machine ?? "localhost", normalizedPattern));
|
||||||
|
WriteError (new ErrorRecord(exc, "NoMatchingCounterSetsFound", ErrorCategory.ObjectNotFound, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessGetCounter()
|
||||||
|
// Does the work to process GetCounterSet parameter set.
|
||||||
|
//
|
||||||
|
private void ProcessGetCounter()
|
||||||
|
{
|
||||||
|
// 1. Combine machine names with paths, if needed, to construct full paths
|
||||||
|
// 2. Translate default paths into current locale
|
||||||
|
// 3. Expand wildcards and validate the paths and write errors for any invalid paths
|
||||||
|
// 4. OpenQuery/ AddCounters
|
||||||
|
// 5. Skip the first reading
|
||||||
|
|
||||||
|
CultureInfo culture = Thread.CurrentThread.CurrentUICulture;
|
||||||
|
List<Tuple<char, char>> characterReplacementList = null;
|
||||||
|
List<string> paths = CombineMachinesAndCounterPaths();
|
||||||
|
uint res = 0;
|
||||||
|
|
||||||
|
if (!_defaultCounters)
|
||||||
|
{
|
||||||
|
_cultureAndSpecialCharacterMap.TryGetValue(culture.LCID, out characterReplacementList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StringCollection allExpandedPaths = new StringCollection();
|
||||||
|
foreach (string path in paths)
|
||||||
|
{
|
||||||
|
string localizedPath = path;
|
||||||
|
if (_defaultCounters)
|
||||||
|
{
|
||||||
|
res = _pdhHelper.TranslateLocalCounterPath(path, out localizedPath);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.CurrentCulture, _resourceMgr.GetString("CounterPathTranslationFailed"), res);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterPathTranslationFailed", ErrorCategory.InvalidResult, null));
|
||||||
|
|
||||||
|
localizedPath = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (characterReplacementList != null)
|
||||||
|
{
|
||||||
|
foreach (Tuple<char, char> pair in characterReplacementList)
|
||||||
|
{
|
||||||
|
localizedPath = localizedPath.Replace(pair.Item1, pair.Item2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringCollection expandedPaths;
|
||||||
|
res = _pdhHelper.ExpandWildCardPath(localizedPath, out expandedPaths);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
WriteDebug("Could not expand path " + localizedPath);
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string expandedPath in expandedPaths)
|
||||||
|
{
|
||||||
|
if (!_pdhHelper.IsPathValid(expandedPath))
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.CurrentCulture, _resourceMgr.GetString("CounterPathIsInvalid"), localizedPath);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterPathIsInvalid", ErrorCategory.InvalidResult, null));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
allExpandedPaths.Add(expandedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allExpandedPaths.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = _pdhHelper.OpenQuery();
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
}
|
||||||
|
res = _pdhHelper.AddCounters(ref allExpandedPaths, true);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceCounterSampleSet nextSet;
|
||||||
|
|
||||||
|
bool bSkip = true;
|
||||||
|
uint sampleReads = 0;
|
||||||
|
|
||||||
|
if (Continuous.IsPresent)
|
||||||
|
{
|
||||||
|
_maxSamples = KEEP_ON_SAMPLING;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// read the first set just to get the initial values
|
||||||
|
res = _pdhHelper.ReadNextSet (out nextSet, bSkip);
|
||||||
|
|
||||||
|
if (res == 0)
|
||||||
|
{
|
||||||
|
//Display valid data
|
||||||
|
if (!bSkip)
|
||||||
|
{
|
||||||
|
WriteSampleSetObject (nextSet);
|
||||||
|
sampleReads++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Don't need to skip anymore
|
||||||
|
bSkip = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (res == PdhResults.PDH_NO_DATA || res == PdhResults.PDH_INVALID_DATA)
|
||||||
|
{
|
||||||
|
// The provider may not be running.
|
||||||
|
// We should keep on trying - but skip the next valid reading.
|
||||||
|
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
|
||||||
|
bSkip = true;
|
||||||
|
|
||||||
|
// Count this failed attempt as a sample:
|
||||||
|
sampleReads++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unexpected error, return
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_maxSamples != KEEP_ON_SAMPLING && sampleReads >= _maxSamples)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cancelled = _cancelEventArrived.WaitOne((int)_sampleInterval * 1000, true);
|
||||||
|
if (cancelled)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReportPdhError(uint res, bool bTerminate)
|
||||||
|
{
|
||||||
|
string msg;
|
||||||
|
uint formatRes = CommonUtilities.FormatMessageFromModule(res, "pdh.dll", out msg);
|
||||||
|
if (formatRes != 0)
|
||||||
|
{
|
||||||
|
msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterApiError"), res);
|
||||||
|
}
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
if (bTerminate)
|
||||||
|
{
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CombineMachinesAndCounterPaths() helper.
|
||||||
|
// For paths that do not contain machine names, creates a path for each machine in machineNames.
|
||||||
|
// Paths already containing a machine name will be preserved.
|
||||||
|
//
|
||||||
|
private List<string> CombineMachinesAndCounterPaths ()
|
||||||
|
{
|
||||||
|
List<string> retColl = new List<string>();
|
||||||
|
|
||||||
|
if (_computerName.Length == 0)
|
||||||
|
{
|
||||||
|
retColl.AddRange(_accumulatedCounters);
|
||||||
|
return retColl;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string path in _accumulatedCounters)
|
||||||
|
{
|
||||||
|
if (path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase)) //NOTE: can we do anything smarter here?
|
||||||
|
{
|
||||||
|
retColl.Add (path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (string machine in _computerName)
|
||||||
|
{
|
||||||
|
if (machine.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
retColl.Add (machine + "\\" + path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retColl.Add ("\\\\" + machine + "\\" + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retColl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WriteSampleSetObject() helper.
|
||||||
|
// In addition to writing the PerformanceCounterSampleSet object,
|
||||||
|
// it writes a single error if one of the samples has an invalid (non-zero) status.
|
||||||
|
//
|
||||||
|
private void WriteSampleSetObject(PerformanceCounterSampleSet set)
|
||||||
|
{
|
||||||
|
foreach (PerformanceCounterSample sample in set.CounterSamples)
|
||||||
|
{
|
||||||
|
if (sample.Status != 0)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterSampleDataInvalid"));
|
||||||
|
Exception exc = new Exception(msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteObject (set);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,111 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2007 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create the PowerShell snap-in used to register the
|
||||||
|
/// Get-WinEvent cmdlet. Declaring the PSSnapIn class identifies
|
||||||
|
/// this .cs file as a PowerShell snap-in.
|
||||||
|
/// </summary>
|
||||||
|
[RunInstaller(true)]
|
||||||
|
public class GetEventPSSnapIn : PSSnapIn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Create an instance of the GetEventPSSnapIn class.
|
||||||
|
/// </summary>
|
||||||
|
public GetEventPSSnapIn()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify the name of the PowerShell snap-in.
|
||||||
|
/// </summary>
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "Microsoft.Powershell.GetEvent";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify the vendor of the PowerShell snap-in.
|
||||||
|
/// </summary>
|
||||||
|
public override string Vendor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "Microsoft";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get resource information for vendor. This is a string of format: resourceBaseName,resourceName.
|
||||||
|
/// </summary>
|
||||||
|
public override string VendorResource
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "GetEventResources,Vendor";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the description of the PowerShell snap-in.
|
||||||
|
/// </summary>
|
||||||
|
public override string Description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "This PS snap-in contains Get-WinEvent cmdlet used to read Windows event log data and configuration.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get resource information for description. This is a string of format: resourceBaseName,resourceName.
|
||||||
|
/// </summary>
|
||||||
|
public override string DescriptionResource
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "GetEventResources,Description";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get type files to be used for this mshsnapin.
|
||||||
|
/// </summary>
|
||||||
|
public override string[] Types
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _types;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string[] _types = new string[] {"getevent.types.ps1xml"};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get format files to be used for this mshsnapin.
|
||||||
|
/// </summary>
|
||||||
|
public override string[] Formats
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _formats;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string[] _formats = new string[] {"Event.format.ps1xml"};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,676 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2008 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Net;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security;
|
||||||
|
using System.Security.Principal;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Microsoft.Powershell.Commands.GetCounter.PdhNative;
|
||||||
|
using Microsoft.PowerShell.Commands.GetCounter;
|
||||||
|
using Microsoft.PowerShell.Commands.Diagnostics.Common;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands
|
||||||
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Class that implements the Get-Counter cmdlet.
|
||||||
|
///
|
||||||
|
[Cmdlet("Import", "Counter", DefaultParameterSetName = "GetCounterSet", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=138338")]
|
||||||
|
public sealed class ImportCounterCommand : PSCmdlet
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Path parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Position = 0,
|
||||||
|
Mandatory = true,
|
||||||
|
ValueFromPipeline = true,
|
||||||
|
ValueFromPipelineByPropertyName = true,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[Alias("PSPath")]
|
||||||
|
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public string[] Path
|
||||||
|
{
|
||||||
|
get {return _path;}
|
||||||
|
set {_path = value;}
|
||||||
|
}
|
||||||
|
private string[] _path;
|
||||||
|
|
||||||
|
private StringCollection _resolvedPaths = new StringCollection();
|
||||||
|
|
||||||
|
private List<string> _accumulatedFileNames = new List<string>();
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListSet parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = true,
|
||||||
|
ParameterSetName="ListSetSet",
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[AllowEmptyCollection]
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public string[] ListSet
|
||||||
|
{
|
||||||
|
get {return _listSet;}
|
||||||
|
set {_listSet = value;}
|
||||||
|
}
|
||||||
|
private string[] _listSet = new string[0];
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// StartTime parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
public DateTime StartTime
|
||||||
|
{
|
||||||
|
get {return _startTime;}
|
||||||
|
set {_startTime = value;}
|
||||||
|
}
|
||||||
|
private DateTime _startTime = DateTime.MinValue;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// EndTime parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
public DateTime EndTime
|
||||||
|
{
|
||||||
|
get {return _endTime;}
|
||||||
|
set {_endTime = value;}
|
||||||
|
}
|
||||||
|
private DateTime _endTime = DateTime.MaxValue;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Counter parameter
|
||||||
|
//
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = false,
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[AllowEmptyCollection]
|
||||||
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Scope = "member",
|
||||||
|
Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public string[] Counter
|
||||||
|
{
|
||||||
|
get {return _counter;}
|
||||||
|
set {_counter = value;}
|
||||||
|
}
|
||||||
|
private string[] _counter = new string[0];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Summary switch
|
||||||
|
//
|
||||||
|
[Parameter(ParameterSetName="SummarySet")]
|
||||||
|
public SwitchParameter Summary
|
||||||
|
{
|
||||||
|
get {return _summary;}
|
||||||
|
set{_summary = value;}
|
||||||
|
}
|
||||||
|
private SwitchParameter _summary;
|
||||||
|
|
||||||
|
//
|
||||||
|
// MaxSamples parameter
|
||||||
|
//
|
||||||
|
private const Int64 KEEP_ON_SAMPLING = -1;
|
||||||
|
[Parameter(
|
||||||
|
ParameterSetName="GetCounterSet",
|
||||||
|
ValueFromPipeline = false,
|
||||||
|
ValueFromPipelineByPropertyName = false,
|
||||||
|
HelpMessageBaseName = "GetEventResources")]
|
||||||
|
[ValidateRange((Int64)1, Int64.MaxValue)]
|
||||||
|
public Int64 MaxSamples
|
||||||
|
{
|
||||||
|
get {return _maxSamples;}
|
||||||
|
set {_maxSamples = value;}
|
||||||
|
}
|
||||||
|
private Int64 _maxSamples = KEEP_ON_SAMPLING;
|
||||||
|
|
||||||
|
|
||||||
|
private ResourceManager _resourceMgr = null;
|
||||||
|
|
||||||
|
private PdhHelper _pdhHelper = null;
|
||||||
|
|
||||||
|
private bool _stopping = false;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// AccumulatePipelineFileNames() accumulates counter file paths in the pipeline scenario:
|
||||||
|
// we do not want to construct a Pdh query until all the file names are supplied.
|
||||||
|
//
|
||||||
|
private void AccumulatePipelineFileNames()
|
||||||
|
{
|
||||||
|
_accumulatedFileNames.AddRange(_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// BeginProcessing() is invoked once per pipeline
|
||||||
|
//
|
||||||
|
protected override void BeginProcessing()
|
||||||
|
{
|
||||||
|
_resourceMgr = new ResourceManager("GetEventResources", Assembly.GetExecutingAssembly());
|
||||||
|
_pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// EndProcessing() is invoked once per pipeline
|
||||||
|
//
|
||||||
|
protected override void EndProcessing()
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resolve and validate the Path argument: present for all parametersets.
|
||||||
|
//
|
||||||
|
if (!ResolveFilePaths ())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ValidateFilePaths();
|
||||||
|
|
||||||
|
switch (ParameterSetName)
|
||||||
|
{
|
||||||
|
case "ListSetSet":
|
||||||
|
ProcessListSet();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "GetCounterSet":
|
||||||
|
ProcessGetCounter();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "SummarySet":
|
||||||
|
ProcessSummary();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "Invalid parameter set name: {0}", ParameterSetName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pdhHelper.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle Control-C
|
||||||
|
//
|
||||||
|
protected override void StopProcessing()
|
||||||
|
{
|
||||||
|
_stopping = true;
|
||||||
|
_pdhHelper.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessRecord() override.
|
||||||
|
// This is the main entry point for the cmdlet.
|
||||||
|
//
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
|
||||||
|
AccumulatePipelineFileNames();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessSummary().
|
||||||
|
// Does the work to process Summary parameter set.
|
||||||
|
//
|
||||||
|
private void ProcessSummary()
|
||||||
|
{
|
||||||
|
uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CounterFileInfo summaryObj;
|
||||||
|
res = _pdhHelper.GetFilesSummary (out summaryObj);
|
||||||
|
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteObject(summaryObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessListSet().
|
||||||
|
// Does the work to process ListSet parameter set.
|
||||||
|
//
|
||||||
|
private void ProcessListSet()
|
||||||
|
{
|
||||||
|
|
||||||
|
uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringCollection machineNames = new StringCollection();
|
||||||
|
res = _pdhHelper.EnumBlgFilesMachines(ref machineNames);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string machine in machineNames)
|
||||||
|
{
|
||||||
|
StringCollection counterSets = new StringCollection();
|
||||||
|
res = _pdhHelper.EnumObjects(machine, ref counterSets);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringCollection validPaths = new StringCollection();
|
||||||
|
|
||||||
|
foreach (string pattern in _listSet)
|
||||||
|
{
|
||||||
|
bool bMatched = false;
|
||||||
|
|
||||||
|
WildcardPattern wildLogPattern = new WildcardPattern(pattern, WildcardOptions.IgnoreCase);
|
||||||
|
|
||||||
|
foreach (string counterSet in counterSets)
|
||||||
|
{
|
||||||
|
if (!wildLogPattern.IsMatch(counterSet))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StringCollection counterSetCounters = new StringCollection();
|
||||||
|
StringCollection counterSetInstances = new StringCollection();
|
||||||
|
|
||||||
|
res = _pdhHelper.EnumObjectItems(machine, counterSet, ref counterSetCounters, ref counterSetInstances);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] instanceArray = new string[counterSetInstances.Count];
|
||||||
|
int i = 0;
|
||||||
|
foreach (string instance in counterSetInstances)
|
||||||
|
{
|
||||||
|
instanceArray[i++] = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, string[]> counterInstanceMapping = new Dictionary<string, string[]>();
|
||||||
|
foreach (string counter in counterSetCounters)
|
||||||
|
{
|
||||||
|
counterInstanceMapping.Add(counter, instanceArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceCounterCategoryType categoryType = PerformanceCounterCategoryType.Unknown;
|
||||||
|
if (counterSetInstances.Count > 1)
|
||||||
|
{
|
||||||
|
categoryType = PerformanceCounterCategoryType.MultiInstance;
|
||||||
|
}
|
||||||
|
else //if (counterSetInstances.Count == 1) //???
|
||||||
|
{
|
||||||
|
categoryType = PerformanceCounterCategoryType.SingleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
string setHelp = _pdhHelper.GetCounterSetHelp(machine, counterSet);
|
||||||
|
|
||||||
|
CounterSet setObj = new CounterSet(counterSet, machine, categoryType, setHelp, ref counterInstanceMapping);
|
||||||
|
WriteObject (setObj);
|
||||||
|
bMatched = true;
|
||||||
|
}
|
||||||
|
if (!bMatched)
|
||||||
|
{
|
||||||
|
string msg = _resourceMgr.GetString("NoMatchingCounterSetsInFile");
|
||||||
|
Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg,
|
||||||
|
CommonUtilities.StringArrayToString(_resolvedPaths),
|
||||||
|
pattern));
|
||||||
|
WriteError (new ErrorRecord(exc, "NoMatchingCounterSetsInFile", ErrorCategory.ObjectNotFound, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ProcessGetCounter()
|
||||||
|
// Does the work to process GetCounterSet parameter set.
|
||||||
|
//
|
||||||
|
private void ProcessGetCounter()
|
||||||
|
{
|
||||||
|
// Validate StartTime-EndTime, if present
|
||||||
|
if (_startTime != DateTime.MinValue || _endTime != DateTime.MaxValue)
|
||||||
|
{
|
||||||
|
if (_startTime >= _endTime)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterInvalidDateRange"));
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterInvalidDateRange", ErrorCategory.InvalidArgument, null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringCollection validPaths = new StringCollection();
|
||||||
|
if (_counter.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (string path in _counter)
|
||||||
|
{
|
||||||
|
StringCollection expandedPaths;
|
||||||
|
res = _pdhHelper.ExpandWildCardPath(path, out expandedPaths);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
WriteDebug(path);
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string expandedPath in expandedPaths)
|
||||||
|
{
|
||||||
|
if (!_pdhHelper.IsPathValid(expandedPath))
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterPathIsInvalid"), path);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterPathIsInvalid", ErrorCategory.InvalidResult, null));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
validPaths.Add(expandedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validPaths.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = _pdhHelper.GetValidPathsFromFiles(ref validPaths);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validPaths.Count == 0)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterPathsInFilesInvalid"));
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterPathsInFilesInvalid", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
res = _pdhHelper.OpenQuery();
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_startTime != DateTime.MinValue || _endTime != DateTime.MaxValue)
|
||||||
|
{
|
||||||
|
res = _pdhHelper.SetQueryTimeRange(_startTime, _endTime);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = _pdhHelper.AddCounters(ref validPaths, true);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceCounterSampleSet nextSet;
|
||||||
|
|
||||||
|
uint samplesRead = 0;
|
||||||
|
|
||||||
|
while (!_stopping)
|
||||||
|
{
|
||||||
|
res = _pdhHelper.ReadNextSet (out nextSet, false);
|
||||||
|
if (res == PdhResults.PDH_NO_MORE_DATA)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (res != 0 && res != PdhResults.PDH_INVALID_DATA)
|
||||||
|
{
|
||||||
|
ReportPdhError(res, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Display data
|
||||||
|
//
|
||||||
|
WriteSampleSetObject (nextSet, (samplesRead == 0));
|
||||||
|
|
||||||
|
samplesRead++;
|
||||||
|
|
||||||
|
if (_maxSamples != KEEP_ON_SAMPLING && samplesRead >= _maxSamples)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ValidateFilePaths() helper.
|
||||||
|
// Validates the _resolvedPaths: present for all parametersets.
|
||||||
|
// We cannot have more than 32 blg files, or more than one CSV or TSC file.
|
||||||
|
// Files have to all be of the same type (.blg, .csv, .tsv).
|
||||||
|
//
|
||||||
|
private void ValidateFilePaths()
|
||||||
|
{
|
||||||
|
Debug.Assert(_resolvedPaths.Count > 0);
|
||||||
|
|
||||||
|
string firstExt = System.IO.Path.GetExtension(_resolvedPaths[0]);
|
||||||
|
foreach (string fileName in _resolvedPaths)
|
||||||
|
{
|
||||||
|
|
||||||
|
WriteVerbose(fileName);
|
||||||
|
string curExtension = System.IO.Path.GetExtension(fileName);
|
||||||
|
|
||||||
|
if (!curExtension.Equals(".blg", StringComparison.CurrentCultureIgnoreCase)
|
||||||
|
&& !curExtension.Equals(".csv", StringComparison.CurrentCultureIgnoreCase)
|
||||||
|
&& !curExtension.Equals(".tsv", StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterNotALogFile"), fileName);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterNotALogFile", ErrorCategory.InvalidResult, null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!curExtension.Equals(firstExt, StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterNoMixedLogTypes"), fileName);
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterNoMixedLogTypes", ErrorCategory.InvalidResult, null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstExt.Equals(".blg", StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
if (_resolvedPaths.Count > 32)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("Counter32FileLimit"));
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "Counter32FileLimit", ErrorCategory.InvalidResult, null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_resolvedPaths.Count > 1)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("Counter1FileLimit"));
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "Counter1FileLimit", ErrorCategory.InvalidResult, null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ResolveFilePath helper.
|
||||||
|
// Returns a string collection of resolved file paths.
|
||||||
|
// Writes non-terminating errors for invalid paths
|
||||||
|
// and returns an empty colleciton.
|
||||||
|
//
|
||||||
|
bool ResolveFilePaths()
|
||||||
|
{
|
||||||
|
|
||||||
|
StringCollection retColl = new StringCollection();
|
||||||
|
|
||||||
|
foreach (string origPath in _accumulatedFileNames)
|
||||||
|
{
|
||||||
|
|
||||||
|
Collection<PathInfo> resolvedPathSubset = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
resolvedPathSubset = SessionState.Path.GetResolvedPSPathFromPSPath(origPath);
|
||||||
|
}
|
||||||
|
catch (PSNotSupportedException notSupported)
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(notSupported, "", ErrorCategory.ObjectNotFound, origPath));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
catch (System.Management.Automation.DriveNotFoundException driveNotFound)
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(driveNotFound, "", ErrorCategory.ObjectNotFound, origPath));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
catch (ProviderNotFoundException providerNotFound)
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(providerNotFound, "", ErrorCategory.ObjectNotFound, origPath));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
catch (ItemNotFoundException pathNotFound)
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(pathNotFound, "", ErrorCategory.ObjectNotFound, origPath));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
catch(Exception exc)
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(exc, "", ErrorCategory.ObjectNotFound, origPath));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PathInfo pi in resolvedPathSubset)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check the provider: only FileSystem provider paths are acceptable.
|
||||||
|
//
|
||||||
|
if (pi.Provider.Name != "FileSystem")
|
||||||
|
{
|
||||||
|
string msg = _resourceMgr.GetString("NotAFileSystemPath");
|
||||||
|
Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg, origPath));
|
||||||
|
WriteError(new ErrorRecord(exc, "NotAFileSystemPath", ErrorCategory.InvalidArgument, origPath));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_resolvedPaths.Add(pi.ProviderPath.ToLower(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (_resolvedPaths.Count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReportPdhError(uint res, bool bTerminate)
|
||||||
|
{
|
||||||
|
string msg;
|
||||||
|
uint formatRes = CommonUtilities.FormatMessageFromModule(res, "pdh.dll", out msg);
|
||||||
|
if (formatRes != 0)
|
||||||
|
{
|
||||||
|
msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterApiError"), res);
|
||||||
|
}
|
||||||
|
Exception exc = new Exception (msg);
|
||||||
|
if (bTerminate)
|
||||||
|
{
|
||||||
|
ThrowTerminatingError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WriteSampleSetObject() helper.
|
||||||
|
// In addition to writing the PerformanceCounterSampleSet object,
|
||||||
|
// it writes a single error if one of the samples has an invalid (non-zero) status.
|
||||||
|
// The only exception is the first set, where we allow for the formatted value to be 0 -
|
||||||
|
// this is expected for CSV and TSV files.
|
||||||
|
|
||||||
|
private void WriteSampleSetObject(PerformanceCounterSampleSet set, bool firstSet)
|
||||||
|
{
|
||||||
|
if (!firstSet)
|
||||||
|
{
|
||||||
|
foreach (PerformanceCounterSample sample in set.CounterSamples)
|
||||||
|
{
|
||||||
|
if (sample.Status != 0)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterSampleDataInvalid"));
|
||||||
|
Exception exc = new Exception(msg);
|
||||||
|
WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteObject (set);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2007 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Diagnostics.Eventing;
|
||||||
|
using System.Diagnostics.Eventing.Reader;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Xml;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerShell.Commands
|
||||||
|
{
|
||||||
|
///
|
||||||
|
/// Class that implements the New-WinEvent cmdlet.
|
||||||
|
/// This cmdlet writes a new Etw event using the provider specified in parameter.
|
||||||
|
///
|
||||||
|
[Cmdlet(VerbsCommon.New, "WinEvent", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=217469")]
|
||||||
|
public sealed class NewWinEventCommand : PSCmdlet
|
||||||
|
{
|
||||||
|
private ProviderMetadata providerMetadata;
|
||||||
|
private EventDescriptor? eventDescriptor;
|
||||||
|
|
||||||
|
private const string TemplateTag = "template";
|
||||||
|
private const string DataTag = "data";
|
||||||
|
private ResourceManager _resourceMgr = new ResourceManager("GetEventResources", typeof(NewWinEventCommand).GetTypeInfo().Assembly);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ProviderName
|
||||||
|
/// </summary>
|
||||||
|
[Parameter(
|
||||||
|
Position = 0,
|
||||||
|
Mandatory = true,
|
||||||
|
ParameterSetName = ParameterAttribute.AllParameterSets)]
|
||||||
|
public string ProviderName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return providerName;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
providerName = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private string providerName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Id (EventId defined in manifest file)
|
||||||
|
/// </summary>
|
||||||
|
[Parameter(
|
||||||
|
Position = 1,
|
||||||
|
Mandatory = true,
|
||||||
|
ParameterSetName = ParameterAttribute.AllParameterSets)]
|
||||||
|
public int Id
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
id = value;
|
||||||
|
idSpecified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int id;
|
||||||
|
private bool idSpecified = false;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Version (event version)
|
||||||
|
/// </summary>
|
||||||
|
[Parameter(
|
||||||
|
Mandatory = false,
|
||||||
|
ParameterSetName = ParameterAttribute.AllParameterSets)]
|
||||||
|
public byte Version
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
version = value;
|
||||||
|
versionSpecified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private byte version;
|
||||||
|
private bool versionSpecified = false;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event Payload
|
||||||
|
/// </summary>
|
||||||
|
[Parameter(
|
||||||
|
Position = 2,
|
||||||
|
Mandatory = false,
|
||||||
|
ParameterSetName = ParameterAttribute.AllParameterSets),
|
||||||
|
AllowEmptyCollection,
|
||||||
|
SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||||
|
Target = "Microsoft.PowerShell.Commands",
|
||||||
|
Justification="A string[] is required here because that is the type Powershell supports")]
|
||||||
|
public object[] Payload
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
payload = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private object[] payload;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// BeginProcessing
|
||||||
|
/// </summary>
|
||||||
|
protected override void BeginProcessing()
|
||||||
|
{
|
||||||
|
LoadProvider();
|
||||||
|
LoadEventDescriptor();
|
||||||
|
|
||||||
|
base.BeginProcessing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadProvider()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(this.providerName))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("ProviderNotSpecified")), "ProviderName");
|
||||||
|
}
|
||||||
|
|
||||||
|
using (EventLogSession session = new EventLogSession())
|
||||||
|
{
|
||||||
|
foreach (string providerName in session.GetProviderNames())
|
||||||
|
{
|
||||||
|
if (string.Equals(providerName, this.providerName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.providerMetadata = new ProviderMetadata(providerName);
|
||||||
|
}
|
||||||
|
catch (EventLogException exc)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("ProviderMetadataUnavailable"), providerName, exc.Message);
|
||||||
|
throw new Exception(msg, exc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.providerMetadata == null)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("NoProviderFound"), providerName);
|
||||||
|
throw new ArgumentException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadEventDescriptor()
|
||||||
|
{
|
||||||
|
if (idSpecified)
|
||||||
|
{
|
||||||
|
List<EventMetadata> matchedEvents = new List<EventMetadata>();
|
||||||
|
foreach (EventMetadata emd in this.providerMetadata.Events)
|
||||||
|
{
|
||||||
|
if (emd.Id == this.id)
|
||||||
|
{
|
||||||
|
matchedEvents.Add(emd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedEvents.Count == 0)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture,
|
||||||
|
_resourceMgr.GetString("IncorrectEventId"),
|
||||||
|
this.id,
|
||||||
|
this.providerName);
|
||||||
|
throw new EventWriteException(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventMetadata matchedEvent = null;
|
||||||
|
if (!versionSpecified && matchedEvents.Count == 1)
|
||||||
|
{
|
||||||
|
matchedEvent = matchedEvents[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (versionSpecified)
|
||||||
|
{
|
||||||
|
foreach (EventMetadata emd in matchedEvents)
|
||||||
|
{
|
||||||
|
if (emd.Version == this.version)
|
||||||
|
{
|
||||||
|
matchedEvent = emd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matchedEvent == null)
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture,
|
||||||
|
_resourceMgr.GetString("IncorrectEventVersion"),
|
||||||
|
this.version,
|
||||||
|
this.id,
|
||||||
|
this.providerName);
|
||||||
|
|
||||||
|
throw new EventWriteException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string msg = string.Format(CultureInfo.InvariantCulture,
|
||||||
|
_resourceMgr.GetString("VersionNotSpecified"),
|
||||||
|
this.id,
|
||||||
|
this.providerName);
|
||||||
|
|
||||||
|
throw new EventWriteException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerifyTemplate(matchedEvent);
|
||||||
|
this.eventDescriptor = CreateEventDescriptor(this.providerMetadata, matchedEvent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("EventIdNotSpecified")), "Id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool VerifyTemplate(EventMetadata emd)
|
||||||
|
{
|
||||||
|
if (emd.Template != null)
|
||||||
|
{
|
||||||
|
XmlReaderSettings readerSettings = new XmlReaderSettings
|
||||||
|
{
|
||||||
|
CheckCharacters = false,
|
||||||
|
IgnoreComments = true,
|
||||||
|
IgnoreProcessingInstructions = true,
|
||||||
|
MaxCharactersInDocument = 0, // no limit
|
||||||
|
ConformanceLevel = ConformanceLevel.Fragment,
|
||||||
|
#if !CORECLR
|
||||||
|
XmlResolver = null,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int definedParameterCount = 0;
|
||||||
|
using (XmlReader reader = XmlReader.Create(new StringReader(emd.Template), readerSettings))
|
||||||
|
{
|
||||||
|
if (reader.ReadToFollowing(TemplateTag))
|
||||||
|
{
|
||||||
|
bool found = reader.ReadToDescendant(DataTag);
|
||||||
|
while (found)
|
||||||
|
{
|
||||||
|
definedParameterCount++;
|
||||||
|
found = reader.ReadToFollowing(DataTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this.payload == null && definedParameterCount != 0)
|
||||||
|
|| ((this.payload != null) && this.payload.Length != definedParameterCount))
|
||||||
|
{
|
||||||
|
string warning = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("PayloadMismatch"), this.id, emd.Template);
|
||||||
|
WriteWarning(warning);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EventDescriptor CreateEventDescriptor(ProviderMetadata providerMetaData, EventMetadata emd)
|
||||||
|
{
|
||||||
|
long keywords = 0;
|
||||||
|
foreach (EventKeyword keyword in emd.Keywords)
|
||||||
|
{
|
||||||
|
keywords |= keyword.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte channel = 0;
|
||||||
|
foreach (EventLogLink logLink in providerMetaData.LogLinks)
|
||||||
|
{
|
||||||
|
if (string.Equals(logLink.LogName, emd.LogLink.LogName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
break;
|
||||||
|
channel++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EventDescriptor(
|
||||||
|
(int) emd.Id,
|
||||||
|
emd.Version,
|
||||||
|
channel,
|
||||||
|
(byte) emd.Level.Value,
|
||||||
|
(byte) emd.Opcode.Value,
|
||||||
|
emd.Task.Value,
|
||||||
|
keywords);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ProcessRecord
|
||||||
|
/// </summary>
|
||||||
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
using (EventProvider provider = new EventProvider(this.providerMetadata.Id))
|
||||||
|
{
|
||||||
|
EventDescriptor ed = this.eventDescriptor.Value;
|
||||||
|
|
||||||
|
if (this.payload != null && this.payload.Length > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < this.payload.Length; i++)
|
||||||
|
{
|
||||||
|
if (this.payload[i] == null)
|
||||||
|
{
|
||||||
|
this.payload[i] = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
provider.WriteEvent(ref ed, this.payload);
|
||||||
|
} else {
|
||||||
|
provider.WriteEvent(ref ed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.ProcessRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EndProcessing
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndProcessing()
|
||||||
|
{
|
||||||
|
if (this.providerMetadata != null)
|
||||||
|
providerMetadata.Dispose();
|
||||||
|
|
||||||
|
base.EndProcessing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class EventWriteException : Exception
|
||||||
|
{
|
||||||
|
internal EventWriteException(string msg, Exception innerException)
|
||||||
|
: base (msg, innerException) {}
|
||||||
|
|
||||||
|
internal EventWriteException(string msg)
|
||||||
|
: base (msg) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) Microsoft. All rights reserved.
|
||||||
|
//
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.ConstrainedExecution;
|
||||||
|
|
||||||
|
namespace Microsoft.Powershell.Commands.GetCounter.PdhNative
|
||||||
|
{
|
||||||
|
|
||||||
|
internal sealed class PdhSafeDataSourceHandle : SafeHandle
|
||||||
|
{
|
||||||
|
private PdhSafeDataSourceHandle() : base(IntPtr.Zero, true) { }
|
||||||
|
|
||||||
|
public override bool IsInvalid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return handle == IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
return (PdhHelper.PdhCloseLog(handle, 0) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal sealed class PdhSafeQueryHandle : SafeHandle
|
||||||
|
{
|
||||||
|
private PdhSafeQueryHandle() : base(IntPtr.Zero, true) { }
|
||||||
|
|
||||||
|
public override bool IsInvalid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return handle == IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
|
||||||
|
return (PdhHelper.PdhCloseQuery(handle) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class PdhSafeLogHandle : SafeHandle
|
||||||
|
{
|
||||||
|
private PdhSafeLogHandle() : base(IntPtr.Zero, true) { }
|
||||||
|
|
||||||
|
public override bool IsInvalid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return handle == IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
|
||||||
|
return (PdhHelper.PdhCloseLog(handle, 0) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in new issue
Block a user