Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Collections.Specialized;9using System.ComponentModel;10using System.Diagnostics;11using System.Diagnostics.CodeAnalysis;12using System.Globalization;13using System.IO;14using System.Management.Automation;15using System.Management.Automation.Runspaces;16using System.Net;17using System.Reflection;18using System.Resources;19using System.Security;20using System.Security.Principal;21using System.Text;22using System.Threading;23using System.Xml;24 25using Microsoft.PowerShell.Commands.Diagnostics.Common;26using Microsoft.PowerShell.Commands.GetCounter;27using Microsoft.Powershell.Commands.GetCounter.PdhNative;28 29namespace Microsoft.PowerShell.Commands30{31    ///32    /// Class that implements the Get-Counter cmdlet.33    ///34    [Cmdlet(VerbsData.Import, "Counter", DefaultParameterSetName = "GetCounterSet", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=138338")]35    public sealed class ImportCounterCommand : PSCmdlet36    {37        //38        // Path parameter39        //40        [Parameter(41                Position = 0,42                Mandatory = true,43                ValueFromPipeline = true,44                ValueFromPipelineByPropertyName = true,45                HelpMessageBaseName = "GetEventResources")]46        [Alias("PSPath")]47 48        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",49                            Scope = "member",50                            Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",51                            Justification = "A string[] is required here because that is the type Powershell supports")]52        public string[] Path53        {54            get { return _path; }55 56            set { _path = value; }57        }58 59        private string[] _path;60 61        private StringCollection _resolvedPaths = new StringCollection();62 63        private List<string> _accumulatedFileNames = new List<string>();64 65        //66        // ListSet parameter67        //68        [Parameter(69                Mandatory = true,70                ParameterSetName = "ListSetSet",71                ValueFromPipeline = false,72                ValueFromPipelineByPropertyName = false,73                HelpMessageBaseName = "GetEventResources")]74        [AllowEmptyCollection]75        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",76                            Scope = "member",77                            Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",78                            Justification = "A string[] is required here because that is the type Powershell supports")]79        public string[] ListSet80        {81            get { return _listSet; }82 83            set { _listSet = value; }84        }85 86        private string[] _listSet = Array.Empty<string>();87 88        //89        // StartTime parameter90        //91        [Parameter(92                ValueFromPipeline = false,93                ValueFromPipelineByPropertyName = false,94                ParameterSetName = "GetCounterSet",95                HelpMessageBaseName = "GetEventResources")]96        public DateTime StartTime97        {98            get { return _startTime; }99 100            set { _startTime = value; }101        }102 103        private DateTime _startTime = DateTime.MinValue;104 105        //106        // EndTime parameter107        //108        [Parameter(109                ValueFromPipeline = false,110                ValueFromPipelineByPropertyName = false,111                ParameterSetName = "GetCounterSet",112                HelpMessageBaseName = "GetEventResources")]113        public DateTime EndTime114        {115            get { return _endTime; }116 117            set { _endTime = value; }118        }119 120        private DateTime _endTime = DateTime.MaxValue;121 122        //123        // Counter parameter124        //125        [Parameter(126                Mandatory = false,127                ParameterSetName = "GetCounterSet",128                ValueFromPipeline = false,129                HelpMessageBaseName = "GetEventResources")]130        [AllowEmptyCollection]131        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",132                            Scope = "member",133                            Target = "Microsoft.PowerShell.Commands.GetCounterCommand.ListSet",134                            Justification = "A string[] is required here because that is the type Powershell supports")]135        public string[] Counter136        {137            get { return _counter; }138 139            set { _counter = value; }140        }141 142        private string[] _counter = Array.Empty<string>();143 144        //145        // Summary switch146        //147        [Parameter(ParameterSetName = "SummarySet")]148        public SwitchParameter Summary149        {150            get { return _summary; }151 152            set { _summary = value; }153        }154 155        private SwitchParameter _summary;156 157        //158        // MaxSamples parameter159        //160        private const Int64 KEEP_ON_SAMPLING = -1;161        [Parameter(162                ParameterSetName = "GetCounterSet",163                ValueFromPipeline = false,164                ValueFromPipelineByPropertyName = false,165                HelpMessageBaseName = "GetEventResources")]166        [ValidateRange((Int64)1, Int64.MaxValue)]167        public Int64 MaxSamples168        {169            get { return _maxSamples; }170 171            set { _maxSamples = value; }172        }173 174        private Int64 _maxSamples = KEEP_ON_SAMPLING;175 176        private ResourceManager _resourceMgr = null;177 178        private PdhHelper _pdhHelper = null;179 180        private bool _stopping = false;181 182        //183        // AccumulatePipelineFileNames() accumulates counter file paths in the pipeline scenario:184        // we do not want to construct a Pdh query until all the file names are supplied.185        //186        private void AccumulatePipelineFileNames()187        {188            _accumulatedFileNames.AddRange(_path);189        }190 191        //192        // BeginProcessing() is invoked once per pipeline193        //194        protected override void BeginProcessing()195        {196 197#if CORECLR198            if (Platform.IsIoT)199            {200                // IoT does not have the '$env:windir\System32\pdh.dll' assembly which is required by this cmdlet.201                throw new PlatformNotSupportedException();202            }203 204            // PowerShell 7 requires at least Windows 7,205            // so no version test is needed206            _pdhHelper = new PdhHelper(false);207#else208            _pdhHelper = new PdhHelper(System.Environment.OSVersion.Version.Major < 6);209#endif210            _resourceMgr = Microsoft.PowerShell.Commands.Diagnostics.Common.CommonUtilities.GetResourceManager();211        }212 213        //214        // EndProcessing() is invoked once per pipeline215        //216        protected override void EndProcessing()217        {218            //219            // Resolve and validate the Path argument: present for all parametersets.220            //221            if (!ResolveFilePaths())222            {223                return;224            }225 226            ValidateFilePaths();227 228            switch (ParameterSetName)229            {230                case "ListSetSet":231                    ProcessListSet();232                    break;233 234                case "GetCounterSet":235                    ProcessGetCounter();236                    break;237 238                case "SummarySet":239                    ProcessSummary();240                    break;241 242                default:243                    Debug.Assert(false, $"Invalid parameter set name: {ParameterSetName}");244                    break;245            }246 247            _pdhHelper.Dispose();248        }249 250        //251        // Handle Control-C252        //253        protected override void StopProcessing()254        {255            _stopping = true;256            _pdhHelper.Dispose();257        }258 259        //260        // ProcessRecord() override.261        // This is the main entry point for the cmdlet.262        //263        protected override void ProcessRecord()264        {265            AccumulatePipelineFileNames();266        }267 268        //269        // ProcessSummary().270        // Does the work to process Summary parameter set.271        //272        private void ProcessSummary()273        {274            uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);275            if (res != 0)276            {277                ReportPdhError(res, true);278                return;279            }280 281            CounterFileInfo summaryObj;282            res = _pdhHelper.GetFilesSummary(out summaryObj);283 284            if (res != 0)285            {286                ReportPdhError(res, true);287                return;288            }289 290            WriteObject(summaryObj);291        }292 293        //294        // ProcessListSet().295        // Does the work to process ListSet parameter set.296        //297        private void ProcessListSet()298        {299            uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);300            if (res != 0)301            {302                ReportPdhError(res, true);303                return;304            }305 306            StringCollection machineNames = new StringCollection();307            res = _pdhHelper.EnumBlgFilesMachines(ref machineNames);308            if (res != 0)309            {310                ReportPdhError(res, true);311                return;312            }313 314            foreach (string machine in machineNames)315            {316                StringCollection counterSets = new StringCollection();317                res = _pdhHelper.EnumObjects(machine, ref counterSets);318                if (res != 0)319                {320                    return;321                }322 323                StringCollection validPaths = new StringCollection();324 325                foreach (string pattern in _listSet)326                {327                    bool bMatched = false;328 329                    WildcardPattern wildLogPattern = new WildcardPattern(pattern, WildcardOptions.IgnoreCase);330 331                    foreach (string counterSet in counterSets)332                    {333                        if (!wildLogPattern.IsMatch(counterSet))334                        {335                            continue;336                        }337 338                        StringCollection counterSetCounters = new StringCollection();339                        StringCollection counterSetInstances = new StringCollection();340 341                        res = _pdhHelper.EnumObjectItems(machine, counterSet, ref counterSetCounters, ref counterSetInstances);342                        if (res != 0)343                        {344                            ReportPdhError(res, false);345                            continue;346                        }347 348                        string[] instanceArray = new string[counterSetInstances.Count];349                        int i = 0;350                        foreach (string instance in counterSetInstances)351                        {352                            instanceArray[i++] = instance;353                        }354 355                        Dictionary<string, string[]> counterInstanceMapping = new Dictionary<string, string[]>();356                        foreach (string counter in counterSetCounters)357                        {358                            counterInstanceMapping.Add(counter, instanceArray);359                        }360 361                        PerformanceCounterCategoryType categoryType = PerformanceCounterCategoryType.Unknown;362                        if (counterSetInstances.Count > 1)363                        {364                            categoryType = PerformanceCounterCategoryType.MultiInstance;365                        }366                        else // if (counterSetInstances.Count == 1) //???367                        {368                            categoryType = PerformanceCounterCategoryType.SingleInstance;369                        }370 371                        string setHelp = _pdhHelper.GetCounterSetHelp(machine, counterSet);372 373                        CounterSet setObj = new CounterSet(counterSet, machine, categoryType, setHelp, ref counterInstanceMapping);374                        WriteObject(setObj);375                        bMatched = true;376                    }377 378                    if (!bMatched)379                    {380                        string msg = _resourceMgr.GetString("NoMatchingCounterSetsInFile");381                        Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg,382                        CommonUtilities.StringArrayToString(_resolvedPaths),383                        pattern));384                        WriteError(new ErrorRecord(exc, "NoMatchingCounterSetsInFile", ErrorCategory.ObjectNotFound, null));385                    }386                }387            }388        }389 390        //391        // ProcessGetCounter()392        // Does the work to process GetCounterSet parameter set.393        //394        private void ProcessGetCounter()395        {396            // Validate StartTime-EndTime, if present397            if (_startTime != DateTime.MinValue || _endTime != DateTime.MaxValue)398            {399                if (_startTime >= _endTime)400                {401                    string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterInvalidDateRange"));402                    Exception exc = new Exception(msg);403                    ThrowTerminatingError(new ErrorRecord(exc, "CounterInvalidDateRange", ErrorCategory.InvalidArgument, null));404                    return;405                }406            }407 408            uint res = _pdhHelper.ConnectToDataSource(_resolvedPaths);409            if (res != 0)410            {411                ReportPdhError(res, true);412                return;413            }414 415            StringCollection validPaths = new StringCollection();416            if (_counter.Length > 0)417            {418                foreach (string path in _counter)419                {420                    StringCollection expandedPaths;421                    res = _pdhHelper.ExpandWildCardPath(path, out expandedPaths);422                    if (res != 0)423                    {424                        WriteDebug(path);425                        ReportPdhError(res, false);426                        continue;427                    }428 429                    foreach (string expandedPath in expandedPaths)430                    {431                        if (!_pdhHelper.IsPathValid(expandedPath))432                        {433                            string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterPathIsInvalid"), path);434                            Exception exc = new Exception(msg);435                            WriteError(new ErrorRecord(exc, "CounterPathIsInvalid", ErrorCategory.InvalidResult, null));436 437                            continue;438                        }439 440                        validPaths.Add(expandedPath);441                    }442                }443 444                if (validPaths.Count == 0)445                {446                    return;447                }448            }449            else450            {451                res = _pdhHelper.GetValidPathsFromFiles(ref validPaths);452                if (res != 0)453                {454                    ReportPdhError(res, false);455                }456            }457 458            if (validPaths.Count == 0)459            {460                string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterPathsInFilesInvalid"));461                Exception exc = new Exception(msg);462                ThrowTerminatingError(new ErrorRecord(exc, "CounterPathsInFilesInvalid", ErrorCategory.InvalidResult, null));463            }464 465            res = _pdhHelper.OpenQuery();466            if (res != 0)467            {468                ReportPdhError(res, false);469            }470 471            if (_startTime != DateTime.MinValue || _endTime != DateTime.MaxValue)472            {473                res = _pdhHelper.SetQueryTimeRange(_startTime, _endTime);474                if (res != 0)475                {476                    ReportPdhError(res, true);477                }478            }479 480            res = _pdhHelper.AddCounters(ref validPaths, true);481            if (res != 0)482            {483                ReportPdhError(res, true);484            }485 486            PerformanceCounterSampleSet nextSet;487 488            uint samplesRead = 0;489 490            while (!_stopping)491            {492                res = _pdhHelper.ReadNextSet(out nextSet, false);493                if (res == PdhResults.PDH_NO_MORE_DATA)494                {495                    break;496                }497 498                if (res != 0 && res != PdhResults.PDH_INVALID_DATA)499                {500                    ReportPdhError(res, false);501                    continue;502                }503 504                //505                // Display data506                //507                WriteSampleSetObject(nextSet, (samplesRead == 0));508 509                samplesRead++;510 511                if (_maxSamples != KEEP_ON_SAMPLING && samplesRead >= _maxSamples)512                {513                    break;514                }515            }516        }517 518        //519        // ValidateFilePaths() helper.520        // Validates the _resolvedPaths: present for all parametersets.521        // We cannot have more than 32 blg files, or more than one CSV or TSC file.522        // Files have to all be of the same type (.blg, .csv, .tsv).523        //524        private void ValidateFilePaths()525        {526            Debug.Assert(_resolvedPaths.Count > 0);527 528            string firstExt = System.IO.Path.GetExtension(_resolvedPaths[0]);529            foreach (string fileName in _resolvedPaths)530            {531                WriteVerbose(fileName);532                string curExtension = System.IO.Path.GetExtension(fileName);533 534                if (!curExtension.Equals(".blg", StringComparison.OrdinalIgnoreCase)535                    && !curExtension.Equals(".csv", StringComparison.OrdinalIgnoreCase)536                    && !curExtension.Equals(".tsv", StringComparison.OrdinalIgnoreCase))537                {538                    string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterNotALogFile"), fileName);539                    Exception exc = new Exception(msg);540                    ThrowTerminatingError(new ErrorRecord(exc, "CounterNotALogFile", ErrorCategory.InvalidResult, null));541                    return;542                }543 544                if (!curExtension.Equals(firstExt, StringComparison.OrdinalIgnoreCase))545                {546                    string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterNoMixedLogTypes"), fileName);547                    Exception exc = new Exception(msg);548                    ThrowTerminatingError(new ErrorRecord(exc, "CounterNoMixedLogTypes", ErrorCategory.InvalidResult, null));549                    return;550                }551            }552 553            if (firstExt.Equals(".blg", StringComparison.OrdinalIgnoreCase))554            {555                if (_resolvedPaths.Count > 32)556                {557                    string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("Counter32FileLimit"));558                    Exception exc = new Exception(msg);559                    ThrowTerminatingError(new ErrorRecord(exc, "Counter32FileLimit", ErrorCategory.InvalidResult, null));560                    return;561                }562            }563            else if (_resolvedPaths.Count > 1)564            {565                string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("Counter1FileLimit"));566                Exception exc = new Exception(msg);567                ThrowTerminatingError(new ErrorRecord(exc, "Counter1FileLimit", ErrorCategory.InvalidResult, null));568                return;569            }570        }571 572        //573        // ResolveFilePath helper.574        // Returns a string collection of resolved file paths.575        // Writes non-terminating errors for invalid paths576        // and returns an empty collection.577        //578        private bool ResolveFilePaths()579        {580            StringCollection retColl = new StringCollection();581 582            foreach (string origPath in _accumulatedFileNames)583            {584                Collection<PathInfo> resolvedPathSubset = null;585                try586                {587                    resolvedPathSubset = SessionState.Path.GetResolvedPSPathFromPSPath(origPath);588                }589                catch (PSNotSupportedException notSupported)590                {591                    WriteError(new ErrorRecord(notSupported, string.Empty, ErrorCategory.ObjectNotFound, origPath));592                    continue;593                }594                catch (System.Management.Automation.DriveNotFoundException driveNotFound)595                {596                    WriteError(new ErrorRecord(driveNotFound, string.Empty, ErrorCategory.ObjectNotFound, origPath));597                    continue;598                }599                catch (ProviderNotFoundException providerNotFound)600                {601                    WriteError(new ErrorRecord(providerNotFound, string.Empty, ErrorCategory.ObjectNotFound, origPath));602                    continue;603                }604                catch (ItemNotFoundException pathNotFound)605                {606                    WriteError(new ErrorRecord(pathNotFound, string.Empty, ErrorCategory.ObjectNotFound, origPath));607                    continue;608                }609                catch (Exception exc)610                {611                    WriteError(new ErrorRecord(exc, string.Empty, ErrorCategory.ObjectNotFound, origPath));612                    continue;613                }614 615                foreach (PathInfo pi in resolvedPathSubset)616                {617                    //618                    // Check the provider: only FileSystem provider paths are acceptable.619                    //620                    if (pi.Provider.Name != "FileSystem")621                    {622                        string msg = _resourceMgr.GetString("NotAFileSystemPath");623                        Exception exc = new Exception(string.Format(CultureInfo.InvariantCulture, msg, origPath));624                        WriteError(new ErrorRecord(exc, "NotAFileSystemPath", ErrorCategory.InvalidArgument, origPath));625                        continue;626                    }627 628                    _resolvedPaths.Add(pi.ProviderPath.ToLowerInvariant());629                }630            }631 632            return (_resolvedPaths.Count > 0);633        }634 635        private void ReportPdhError(uint res, bool bTerminate)636        {637            string msg;638            uint formatRes = CommonUtilities.FormatMessageFromModule(res, "pdh.dll", out msg);639            if (formatRes != 0)640            {641                msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterApiError"), res);642            }643 644            Exception exc = new Exception(msg);645            if (bTerminate)646            {647                ThrowTerminatingError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));648            }649            else650            {651                WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));652            }653        }654 655        //656        // WriteSampleSetObject() helper.657        // In addition to writing the PerformanceCounterSampleSet object,658        // it writes a single error if one of the samples has an invalid (non-zero) status.659        // The only exception is the first set, where we allow for the formatted value to be 0 -660        // this is expected for CSV and TSV files.661 662        private void WriteSampleSetObject(PerformanceCounterSampleSet set, bool firstSet)663        {664            if (!firstSet)665            {666                foreach (PerformanceCounterSample sample in set.CounterSamples)667                {668                    if (sample.Status != 0)669                    {670                        string msg = string.Format(CultureInfo.InvariantCulture, _resourceMgr.GetString("CounterSampleDataInvalid"));671                        Exception exc = new Exception(msg);672                        WriteError(new ErrorRecord(exc, "CounterApiError", ErrorCategory.InvalidResult, null));673                        break;674                    }675                }676            }677 678            WriteObject(set);679        }680    }681}682