Update files from Source Depot changeset [SD:700586]

Corresponds to 84837459913bb00660964d19ea07f5e0c7b4b442 in psl-monad.
This commit is contained in:
PowerShell Team 2016-04-28 13:41:25 -07:00 committed by Andrew Schwartzmeyer
parent a7ba3395b9
commit 3998ce06ba
40 changed files with 1631 additions and 484 deletions

View file

@ -63,6 +63,15 @@ namespace Microsoft.PowerShell
}
}
internal bool ShowBanner
{
get
{
Dbg.Assert(dirty, "Parse has not been called yet");
return showBanner;
}
}
internal bool NoExit
{
get
@ -229,7 +238,7 @@ namespace Microsoft.PowerShell
ui.WriteLine("");
}
private void ShowBanner()
private void DisplayBanner()
{
// We need to show the banner only if it has not been already shown in native layer
if (!showInitialPrompt)
@ -699,7 +708,7 @@ namespace Microsoft.PowerShell
if (showBanner && !showHelp)
{
ShowBanner();
DisplayBanner();
}
Dbg.Assert(

View file

@ -10,6 +10,7 @@ using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
@ -36,7 +37,7 @@ using ConsoleHandle = Microsoft.Win32.SafeHandles.SafeFileHandle;
using NakedWin32Handle = System.IntPtr;
using System.Management.Automation.Tracing;
using Microsoft.PowerShell.Telemetry.Internal;
using Debugger = System.Management.Automation.Debugger;
namespace Microsoft.PowerShell
{
@ -51,7 +52,8 @@ namespace Microsoft.PowerShell
:
PSHost,
IDisposable,
IHostSupportsInteractiveSession
IHostSupportsInteractiveSession,
IHostProvidesTelemetryData
{
#region static methods
@ -202,17 +204,8 @@ namespace Microsoft.PowerShell
theConsoleHost.UI.WriteWarningLine(preStartWarning);
}
using (theConsoleHost)
try
{
#region Telemetry
// Data Point to Collect: PowerShell Version on this device
// If null Version is supplied, the Telemetry infrastucture will log an empty value for null
string version = theConsoleHost.ver.ToString();
Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI.TraceMessage("PSCONSOLEHOST_START", new { PSVersion = version });
#endregion
cpp = new CommandLineParameterParser(theConsoleHost, theConsoleHost.ver, bannerText, helpText);
string[] tempArgs = new string[args.GetLength(0)];
args.CopyTo(tempArgs, 0);
@ -239,15 +232,17 @@ namespace Microsoft.PowerShell
else if (cpp.NamedPipeServerMode)
{
ClrFacade.StartProfileOptimization("StartupProfileData-NamedPipeServerMode");
System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode(cpp.ConfigurationName);
System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode(
cpp.ConfigurationName);
exitCode = 0;
}
else if (cpp.SocketServerMode)
{
ClrFacade.StartProfileOptimization("StartupProfileData-SocketServerMode");
System.Management.Automation.Remoting.Server.HyperVSocketMediator.Run(cpp.InitialCommand, cpp.ConfigurationName);
System.Management.Automation.Remoting.Server.HyperVSocketMediator.Run(cpp.InitialCommand,
cpp.ConfigurationName);
exitCode = 0;
}
}
else
{
ClrFacade.StartProfileOptimization(
@ -256,7 +251,14 @@ namespace Microsoft.PowerShell
: "StartupProfileData-NonInteractive");
exitCode = theConsoleHost.Run(cpp, !string.IsNullOrEmpty(preStartWarning));
}
}
finally
{
TelemetryAPI.ReportExitTelemetry(theConsoleHost);
theConsoleHost.Dispose();
}
unchecked
{
return (int)exitCode;
@ -970,6 +972,22 @@ namespace Microsoft.PowerShell
}
}
bool IHostProvidesTelemetryData.HostIsInteractive
{
get
{
return !cpp.NonInteractive && !cpp.AbortStartup &&
((cpp.InitialCommand == null && cpp.File == null) || cpp.NoExit);
}
}
double IHostProvidesTelemetryData.ProfileLoadTimeInMS { get { return _profileLoadTimeInMS; } }
double IHostProvidesTelemetryData.ReadyForInputTimeInMS { get { return _readyForInputTimeInMS; } }
int IHostProvidesTelemetryData.InteractiveCommandCount { get { return _interactiveCommandCount; } }
private double _profileLoadTimeInMS;
private double _readyForInputTimeInMS;
private int _interactiveCommandCount;
#endregion overrides
#region non-overrides
@ -1370,6 +1388,7 @@ namespace Microsoft.PowerShell
RunspaceCreationEventArgs args = new RunspaceCreationEventArgs(initialCommand, skipProfiles, staMode, importSystemModules, configurationName, initialCommandArgs);
CreateRunspace(args);
if (ExitCode == ExitCodeInitFailure) { break; }
if (!noExit && !ui.ReadFromStdin)
@ -1564,6 +1583,9 @@ namespace Microsoft.PowerShell
PSTask.PowershellConsoleStartup, PSKeyword.UseAlwaysOperational);
}
// Record how long it took from process start to runspace open for telemetry.
_readyForInputTimeInMS = (DateTime.Now - Process.GetCurrentProcess().StartTime).TotalMilliseconds;
DoRunspaceInitialization(importSystemModules, skipProfiles, initialCommand, configurationName, initialCommandArgs);
}
@ -1697,10 +1719,21 @@ namespace Microsoft.PowerShell
// 3. host independent profile of the current user
// 4. host specific profile of the current user
var sw = new Stopwatch();
sw.Start();
RunProfile(allUsersProfile, exec);
RunProfile(allUsersHostSpecificProfile, exec);
RunProfile(currentUserProfile, exec);
RunProfile(currentUserHostSpecificProfile, exec);
sw.Stop();
var profileLoadTimeInMs = sw.ElapsedMilliseconds;
if (profileLoadTimeInMs > 500 && cpp.ShowBanner)
{
Console.Error.WriteLine(ConsoleHostStrings.SlowProfileLoadingMessage, profileLoadTimeInMs);
}
_profileLoadTimeInMS = profileLoadTimeInMs;
}
else
{
@ -1708,6 +1741,10 @@ namespace Microsoft.PowerShell
}
}
// Startup is reported after possibly running the profile, but before running the initial command (or file)
// if one is specified.
TelemetryAPI.ReportStartupTelemetry(this);
// If a file was specified as the argument to run, then run it...
if (cpp != null && cpp.File != null)
{
@ -2714,6 +2751,9 @@ namespace Microsoft.PowerShell
parent.PopRunspace();
}
}
if (!inBlockMode)
theConsoleHost._interactiveCommandCount += 1;
}
}
// NTRAID#Windows Out Of Band Releases-915506-2005/09/09

View file

@ -133,13 +133,13 @@
<value>PowerShell[.exe] [-PSConsoleFile &lt;file&gt; | -Version &lt;version&gt;]
[-NoLogo] [-NoExit] [-NoProfile] [-NonInteractive] [-STA]
[-OutputFormat {Text | XML}] [-InputFormat {Text | XML}]
[-ConfigurationName &lt;string&gt;]
[-File fileName [arguments...]] [-ExecutionPolicy &lt;ExecutionPolicy&gt;]
[-Command { - | &lt;script-block&gt; [-args &lt;arg-array&gt;]
| &lt;string&gt; [&lt;CommandParameters&gt;] } ]
[-File fileName [arguments...]] [-ExecutionPolicy &lt;ExecutionPolicy&gt;]
PowerShell[.exe] -Help | -? | /?
-PSConsoleFile
Loads the specified Windows PowerShell console file. To create a console
file, use Export-Console in Windows PowerShell.
@ -170,6 +170,12 @@ PowerShell[.exe] -Help | -? | /?
Describes the format of data sent to Windows PowerShell. Valid values are
"Text" (text strings) or "XML" (serialized CLIXML format).
-ConfigurationName
Specifies a configuration endpoint in which Windows PowerShell is run.
This can be any endpoint registered on the local machine including the
default Windows PowerShell remoting endpoints or a custom endpoint having
specific user role capabilities.
-Command
Executes the specified commands (and any parameters) as though they were
typed at the Windows PowerShell command prompt, and then exits, unless
@ -201,6 +207,7 @@ PowerShell[.exe] -Help | -? | /?
EXAMPLES
PowerShell -PSConsoleFile SqlSnapin.Psc1
PowerShell -version 1.0 -NoLogo -InputFormat text -OutputFormat XML
PowerShell -ConfigurationName AdminRoles
PowerShell -Command {Get-EventLog -LogName security}
PowerShell -Command "&amp; {Get-EventLog -LogName security}"
</value>

View file

@ -185,4 +185,7 @@ The current session does not support debugging; execution will continue.
<data name="ConflictingServerModeParameters" xml:space="preserve">
<value>More than one server mode parameter was specified. Server mode parameters must be used exclusively.</value>
</data>
</root>
<data name="SlowProfileLoadingMessage" xml:space="preserve">
<value>Loading personal and system profiles took {0}ms.</value>
</data>
</root>

View file

@ -124,8 +124,9 @@ Copyright (C) 2016 Microsoft Corporation. All rights reserved.</value>
<data name="ShellHelp" xml:space="preserve">
<value>PowerShell[.exe] [-PSConsoleFile &lt;file&gt; | -Version &lt;version&gt;]
[-NoLogo] [-NoExit] [-Sta] [-Mta] [-NoProfile] [-NonInteractive]
[-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
[-WindowStyle &lt;style&gt;] [-EncodedCommand &lt;Base64EncodedCommand&gt;]
[-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
[-WindowStyle &lt;style&gt;] [-EncodedCommand &lt;Base64EncodedCommand&gt;]
[-ConfigurationName &lt;string&gt;]
[-File &lt;filePath&gt; &lt;args&gt;] [-ExecutionPolicy &lt;ExecutionPolicy&gt;]
[-Command { - | &lt;script-block&gt; [-args &lt;arg-array&gt;]
| &lt;string&gt; [&lt;CommandParameters&gt;] } ]
@ -174,6 +175,12 @@ PowerShell[.exe] -Help | -? | /?
Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.
-ConfigurationName
Specifies a configuration endpoint in which Windows PowerShell is run.
This can be any endpoint registered on the local machine including the
default Windows PowerShell remoting endpoints or a custom endpoint having
specific user role capabilities.
-File
Runs the specified script in the local scope ("dot-sourced"), so that the
@ -220,6 +227,7 @@ PowerShell[.exe] -Help | -? | /?
EXAMPLES
PowerShell -PSConsoleFile SqlSnapIn.Psc1
PowerShell -version 2.0 -NoLogo -InputFormat text -OutputFormat XML
PowerShell -ConfigurationName AdminRoles
PowerShell -Command {Get-EventLog -LogName security}
PowerShell -Command "&amp; {Get-EventLog -LogName security}"

View file

@ -3,8 +3,9 @@ GUID="eb74e8da-9ae2-482a-a648-e96550fb8733"
Author="Microsoft Corporation"
CompanyName="Microsoft Corporation"
Copyright="© Microsoft Corporation. All rights reserved."
ModuleVersion="1.0.0.0"
ModuleVersion="1.0.1.0"
FunctionsToExport = @('Compress-Archive', 'Expand-Archive')
DotNetFrameworkVersion = 4.5
CmdletsToExport = @()
AliasesToExport = @()
NestedModules="Microsoft.PowerShell.Archive.psm1"

File diff suppressed because it is too large Load diff

View file

@ -6,11 +6,13 @@ Copyright (c) Microsoft Corporation. All rights reserved.
using System.Collections.ObjectModel;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Management.Automation.Language;
using System.Management.Automation.Runspaces;
using System.Text.RegularExpressions;
using Microsoft.PowerShell.Telemetry.Internal;
namespace System.Management.Automation
{
@ -518,6 +520,9 @@ namespace System.Management.Automation
// This is the start of the real implementation of autocomplete/intellisense/tab completion
private static CommandCompletion CompleteInputImpl(Ast ast, Token[] tokens, IScriptPosition positionOfCursor, Hashtable options)
{
var sw = new Stopwatch();
sw.Start();
using (var powershell = PowerShell.Create(RunspaceMode.CurrentRunspace))
{
var context = LocalPipeline.GetExecutionContextFromTLS();
@ -585,8 +590,13 @@ namespace System.Management.Automation
}
*/
}
var completionResults = results ?? EmptyCompletionResult;
sw.Stop();
TelemetryAPI.ReportTabCompletionTelemetry(sw.ElapsedMilliseconds, completionResults.Count,
completionResults.Count > 0 ? completionResults[0].ResultType : CompletionResultType.Text);
return new CommandCompletion(
new Collection<CompletionResult>(results ?? EmptyCompletionResult),
new Collection<CompletionResult>(completionResults),
-1,
replacementIndex,
replacementLength);

View file

@ -1376,7 +1376,8 @@ namespace System.Management.Automation
var moduleExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
StringLiterals.PowerShellModuleFileExtension,
StringLiterals.PowerShellDataFileExtension,
StringLiterals.PowerShellDataFileExtension,
StringLiterals.PowerShellNgenAssemblyExtension,
StringLiterals.DependentWorkflowAssemblyExtension,
StringLiterals.PowerShellCmdletizationFileExtension,
StringLiterals.WorkflowFileExtension

View file

@ -3111,8 +3111,9 @@ namespace System.Management.Automation
var moduleExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{ StringLiterals.PowerShellScriptFileExtension,
StringLiterals.PowerShellModuleFileExtension,
StringLiterals.PowerShellDataFileExtension,
StringLiterals.DependentWorkflowAssemblyExtension,
StringLiterals.PowerShellDataFileExtension,
StringLiterals.PowerShellNgenAssemblyExtension,
StringLiterals.DependentWorkflowAssemblyExtension,
StringLiterals.PowerShellCmdletizationFileExtension,
StringLiterals.WorkflowFileExtension
};
@ -4113,7 +4114,7 @@ namespace System.Management.Automation
wordToComplete = WildcardPattern.Escape(wordToComplete, Utils.Separators.StarOrQuestion);
}
if (!defaultRelative && wordToComplete.Length >= 2 && wordToComplete[1] == ':' && char.IsLetter(wordToComplete[0]))
if (!defaultRelative && wordToComplete.Length >= 2 && wordToComplete[1] == ':' && char.IsLetter(wordToComplete[0]) && context.ExecutionContext != null)
{
// We don't actually need the drive, but the drive must be "mounted" in PowerShell before completion
// can succeed. This call will mount the drive if it wasn't already.

View file

@ -607,12 +607,9 @@ namespace System.Management.Automation
do // false loop
{
if (!File.Exists(path))
if (!Utils.NativeFileExists(path))
{
CommandDiscovery.discoveryTracer.TraceError(
"The path does not exist: {0}",
path);
CommandDiscovery.discoveryTracer.TraceError("The path does not exist: {0}", path);
break;
}

View file

@ -60,7 +60,7 @@ namespace System.Management.Automation
Collection<ValidateArgumentsAttribute> validationAttributes = null;
Collection<ArgumentTransformationAttribute> argTransformationAttributes = null;
Collection<string> aliases = null;
string[] aliases = null;
// First, process attributes that aren't type conversions
foreach (Attribute attribute in runtimeDefinedParameter.Attributes)
@ -166,7 +166,7 @@ namespace System.Management.Automation
Collection<ValidateArgumentsAttribute> validationAttributes = null;
Collection<ArgumentTransformationAttribute> argTransformationAttributes = null;
Collection<string> aliases = null;
string[] aliases = null;
foreach (Attribute attr in memberAttributes)
{
@ -179,9 +179,7 @@ namespace System.Management.Automation
this.ArgumentTransformationAttributes = argTransformationAttributes == null
? Utils.EmptyArray<ArgumentTransformationAttribute>()
: argTransformationAttributes.ToArray();
this.Aliases = aliases == null
? Utils.EmptyArray<string>()
: aliases.ToArray();
this.Aliases = aliases ?? Utils.EmptyArray<string>();
}
#endregion ctor
@ -437,7 +435,7 @@ namespace System.Management.Automation
Attribute attribute,
ref Collection<ValidateArgumentsAttribute> validationAttributes,
ref Collection<ArgumentTransformationAttribute> argTransformationAttributes,
ref Collection<string> aliases)
ref string[] aliases)
{
// NTRAID#Windows Out Of Band Releases-926374-2005/12/22-JonN
if (null == attribute)
@ -471,14 +469,15 @@ namespace System.Management.Automation
{
if (aliases == null)
{
aliases = new Collection<string>(aliasAttr.aliasNames);
aliases = aliasAttr.aliasNames;
}
else
{
for (int i = 0; i < aliasAttr.aliasNames.Length; i++)
{
aliases.Add(aliasAttr.aliasNames[i]);
}
var prevAliasNames = aliases;
var newAliasNames = aliasAttr.aliasNames;
aliases = new string[prevAliasNames.Length + newAliasNames.Length];
Array.Copy(prevAliasNames, aliases, prevAliasNames.Length);
Array.Copy(newAliasNames, 0, aliases, prevAliasNames.Length, newAliasNames.Length);
}
return;
}

View file

@ -2643,9 +2643,10 @@ namespace System.Management.Automation
private void OnPSEventReceived(Object sender, PSEventArgs e)
{
if (PSEventReceived != null)
PSEventReceivedEventHandler eventHandler = PSEventReceived;
if (eventHandler != null)
{
PSEventReceived(sender, e);
eventHandler(sender, e);
}
}

View file

@ -7,6 +7,7 @@ using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Management.Automation;
using System.Diagnostics.CodeAnalysis;
@ -381,6 +382,8 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
protected override void BeginProcessing()
{
_timer.Start();
base.BeginProcessing();
if (ShowCommandInfo.IsPresent && Syntax.IsPresent)
@ -522,8 +525,10 @@ namespace Microsoft.PowerShell.Commands
{
CommandOrigin origin = this.MyInvocation.CommandOrigin;
int count = 0;
foreach (CommandInfo result in results)
{
count += 1;
// Only write the command if it is visible to the requestor
if (SessionState.IsVisible(origin, result))
{
@ -556,6 +561,17 @@ namespace Microsoft.PowerShell.Commands
}
}
}
_timer.Stop();
// We want telemtry on commands people look for but don't exist - this should give us an idea
// what sort of commands people expect but either don't exist, or maybe should be installed by default.
// The StartsWith is to avoid logging telemetry when suggestion mode checks the
// current directory for scripts/exes in the current directory and '.' is not in the path.
if (count == 0 && Name != null && Name.Length > 0 && !Name[0].StartsWith(".\\"))
{
Telemetry.Internal.TelemetryAPI.ReportGetCommandFailed(Name, _timer.ElapsedMilliseconds);
}
}
/// <summary>
@ -1396,6 +1412,8 @@ namespace Microsoft.PowerShell.Commands
Collection<WildcardPattern> nounPatterns;
Collection<WildcardPattern> _modulePatterns;
private Stopwatch _timer = new Stopwatch();
#endregion
#region ShowCommandInfo support

View file

@ -2965,7 +2965,7 @@ namespace System.Management.Automation.Runspaces
// Get initial list of public commands in session.
HashSet<CommandInfo> publicCommands = new HashSet<CommandInfo>();
foreach (CommandInfo sessionCommand in initializedRunspace.ExecutionContext.SessionState.InvokeCommand.GetCommands(
"*", CommandTypes.All, true))
"*", CommandTypes.Alias | CommandTypes.Function | CommandTypes.Filter | CommandTypes.Cmdlet, true))
{
if (sessionCommand.Visibility == SessionStateEntryVisibility.Public)
{
@ -3626,15 +3626,12 @@ namespace System.Management.Automation.Runspaces
if (this.DefaultCommandVisibility != SessionStateEntryVisibility.Public)
{
foreach (CommandInfo importedCommand in initializedRunspace.ExecutionContext.SessionState.InvokeCommand.GetCommands(
"*", CommandTypes.All, true))
"*", CommandTypes.Alias | CommandTypes.Function | CommandTypes.Filter | CommandTypes.Cmdlet, true))
{
try
{
// All commands except for the initial session public commands should be made private.
// Exclude ApplicationInfo/ExternalScriptInfo commands as they throw on the setter (because
// visibility is governed via the ExceutionContext.SessionState lists).
if (!(importedCommand is ApplicationInfo) && !(importedCommand is ExternalScriptInfo) &&
(importedCommand.Visibility != this.DefaultCommandVisibility) &&
if ((importedCommand.Visibility != this.DefaultCommandVisibility) &&
!publicCommands.Contains(importedCommand))
{
importedCommand.Visibility = this.DefaultCommandVisibility;
@ -6128,6 +6125,7 @@ if($paths) {
{"Invoke-History", new SessionStateCmdletEntry("Invoke-History", typeof(InvokeHistoryCommand), helpFile) },
{"New-Module", new SessionStateCmdletEntry("New-Module", typeof(NewModuleCommand), helpFile) },
{"New-ModuleManifest", new SessionStateCmdletEntry("New-ModuleManifest", typeof(NewModuleManifestCommand), helpFile) },
{"New-PSRoleCapabilityFile", new SessionStateCmdletEntry("New-PSRoleCapabilityFile", typeof(NewPSRoleCapabilityFileCommand), helpFile) },
{"New-PSSession", new SessionStateCmdletEntry("New-PSSession", typeof(NewPSSessionCommand), helpFile) },
{"New-PSSessionConfigurationFile", new SessionStateCmdletEntry("New-PSSessionConfigurationFile", typeof(NewPSSessionConfigurationFileCommand), helpFile) },
{"New-PSSessionOption", new SessionStateCmdletEntry("New-PSSessionOption", typeof(NewPSSessionOptionCommand), helpFile) },
@ -6159,7 +6157,6 @@ if($paths) {
{"Enable-PSRemoting", new SessionStateCmdletEntry("Enable-PSRemoting", typeof(EnablePSRemotingCommand), helpFile) },
{"Export-Console", new SessionStateCmdletEntry("Export-Console", typeof(ExportConsoleCommand), helpFile) },
{"Get-PSSnapin", new SessionStateCmdletEntry("Get-PSSnapin", typeof(GetPSSnapinCommand), helpFile) },
{"New-PSRoleCapabilityFile", new SessionStateCmdletEntry("New-PSRoleCapabilityFile", typeof(NewPSRoleCapabilityFileCommand), helpFile) },
{"New-PSTransportOption", new SessionStateCmdletEntry("New-PSTransportOption", typeof(NewPSTransportOptionCommand), helpFile) },
{"Remove-PSSnapin", new SessionStateCmdletEntry("Remove-PSSnapin", typeof(RemovePSSnapinCommand), helpFile) },
{"Resume-Job", new SessionStateCmdletEntry("Resume-Job", typeof(ResumeJobCommand), helpFile) },
@ -6189,9 +6186,6 @@ if($paths) {
}
}
internal static readonly CallSite<Func<CallSite, object, object>> CreateModuleInitializerInstance =
CallSite<Func<CallSite, object, object>>.Create(PSCreateInstanceBinder.Get(new CallInfo(0), null));
private static void ExecuteModuleInitializer(Assembly assembly, Type[] assemblyTypes, bool isModuleLoad)
{
for (int i = 0; i < assemblyTypes.Length; i++)
@ -6203,9 +6197,7 @@ if($paths) {
if (isModuleLoad && typeof(IModuleAssemblyInitializer).IsAssignableFrom(type) && type != typeof(IModuleAssemblyInitializer))
{
_assembliesWithModuleInitializerCache.Value[assembly] = true;
var moduleInitializer = (IModuleAssemblyInitializer) CreateModuleInitializerInstance
.Target.Invoke(
CreateModuleInitializerInstance, type);
IModuleAssemblyInitializer moduleInitializer = (IModuleAssemblyInitializer)Activator.CreateInstance(type, true);
moduleInitializer.OnImport();
}
}

View file

@ -24,6 +24,7 @@ using Parser = System.Management.Automation.Language.Parser;
using ScriptBlock = System.Management.Automation.ScriptBlock;
using Token = System.Management.Automation.Language.Token;
using System.Collections.ObjectModel;
using Microsoft.PowerShell.Telemetry.Internal;
#if CORECLR
// Use stub for SecurityZone.
@ -266,7 +267,7 @@ namespace Microsoft.PowerShell.Commands
}
set
{
if (value == null)
if (string.IsNullOrWhiteSpace(value))
{
BaseMaximumVersion = null;
}
@ -1752,6 +1753,8 @@ namespace Microsoft.PowerShell.Commands
if (null != foundModule)
{
SetModuleBaseForEngineModules(foundModule.Name, this.Context);
TelemetryAPI.ReportModuleLoad(foundModule);
}
}
}

View file

@ -1256,8 +1256,18 @@ namespace Microsoft.PowerShell.Commands
currentlyProcessingModules[file] = null;
// Create a fake module info for this file
string extension;
file = file.TrimEnd();
string extension = Path.GetExtension(file);
// In case the file is a Ngen Assembly.
if (file.EndsWith(StringLiterals.PowerShellNgenAssemblyExtension, StringComparison.OrdinalIgnoreCase))
{
extension = StringLiterals.PowerShellNgenAssemblyExtension;
}
else
{
extension = Path.GetExtension(file);
}
ManifestProcessingFlags flags = ManifestProcessingFlags.NullOnFirstError;
// We are creating the ModuleInfo for Get-Module..so ignoring
@ -1334,7 +1344,7 @@ namespace Microsoft.PowerShell.Commands
}
}
else if (extension.Equals(".dll", StringComparison.OrdinalIgnoreCase))
else if (extension.Equals(StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase) || extension.Equals(StringLiterals.PowerShellNgenAssemblyExtension, StringComparison.OrdinalIgnoreCase))
{
moduleInfo.SetModuleType(ModuleType.Binary);
moduleInfo.RootModule = moduleInfo.Path;
@ -2273,12 +2283,18 @@ namespace Microsoft.PowerShell.Commands
}
else
{
string fileName = FixupFileName(moduleBase, assembly, ".dll");
string fileName = FixupFileName(moduleBase, assembly, StringLiterals.PowerShellNgenAssemblyExtension);
string loadMessage = StringUtil.Format(Modules.LoadingFile, "Assembly", fileName);
WriteVerbose(loadMessage);
iss.Assemblies.Add(new SessionStateAssemblyEntry(assembly, fileName));
fixedUpAssemblyPathList.Add(fileName);
fileName = FixupFileName(moduleBase, assembly, StringLiterals.DependentWorkflowAssemblyExtension);
loadMessage = StringUtil.Format(Modules.LoadingFile, "Assembly", fileName);
WriteVerbose(loadMessage);
iss.Assemblies.Add(new SessionStateAssemblyEntry(assembly, fileName));
fixedUpAssemblyPathList.Add(fileName);
doBind = true;
}
}
@ -5244,8 +5260,7 @@ namespace Microsoft.PowerShell.Commands
{
if (typeof(IModuleAssemblyCleanup).IsAssignableFrom(type) && type != typeof(IModuleAssemblyCleanup))
{
var moduleCleanup = (IModuleAssemblyCleanup) PSSnapInHelpers.CreateModuleInitializerInstance.Target.Invoke(
PSSnapInHelpers.CreateModuleInitializerInstance, type);
var moduleCleanup = (IModuleAssemblyCleanup)Activator.CreateInstance(type, true);
moduleCleanup.OnRemove(module);
}
}
@ -5628,8 +5643,10 @@ namespace Microsoft.PowerShell.Commands
var importingModule = 0 != (manifestProcessingFlags & ManifestProcessingFlags.LoadElements);
foreach (string ext in extensions)
// "ni.dll" has a higher priority then ".dll" to be loaded.
for (int i = 0; i < extensions.Length; i++)
{
string ext = extensions[i];
string fileName = fileBaseName + ext;
// Get the resolved file name
@ -5859,7 +5876,16 @@ namespace Microsoft.PowerShell.Commands
var importingModule = 0 != (manifestProcessingFlags & ManifestProcessingFlags.LoadElements);
var writingErrors = 0 != (manifestProcessingFlags & ManifestProcessingFlags.WriteErrors);
string ext = Path.GetExtension(fileName);
// In case the file is a Ngen Assembly.
string ext;
if (fileName.EndsWith(StringLiterals.PowerShellNgenAssemblyExtension, StringComparison.OrdinalIgnoreCase))
{
ext = StringLiterals.PowerShellNgenAssemblyExtension;
}
else
{
ext = Path.GetExtension(fileName);
}
PSModuleInfo module = null;
// If MinimumVersion/RequiredVersion/MaximumVersion has been specified, then only try to process manifest modules...
@ -6113,7 +6139,7 @@ namespace Microsoft.PowerShell.Commands
found = false;
}
}
else if (ext.Equals(".dll", StringComparison.OrdinalIgnoreCase))
else if (ext.Equals(".dll", StringComparison.OrdinalIgnoreCase) || ext.Equals(StringLiterals.PowerShellNgenAssemblyExtension))
{
module = LoadBinaryModule(false, ModuleIntrinsics.GetModuleName(fileName), fileName, null,
moduleBase, ss, options, manifestProcessingFlags, prefix, true, true, out found);

View file

@ -479,22 +479,24 @@ namespace System.Management.Automation
return new Guid();
}
// The extensions of all of the files that can be processed with Import-Module
// The extensions of all of the files that can be processed with Import-Module, put the ni.dll in front of .dll to have higher priority to be loaded.
internal static string[] PSModuleProcessableExtensions = new string[] {
StringLiterals.PowerShellDataFileExtension,
StringLiterals.PowerShellScriptFileExtension,
StringLiterals.PowerShellModuleFileExtension,
StringLiterals.PowerShellCmdletizationFileExtension,
StringLiterals.WorkflowFileExtension,
".dll" };
StringLiterals.PowerShellNgenAssemblyExtension,
StringLiterals.DependentWorkflowAssemblyExtension};
// A list of the extensions to check for implicit module loading and discovery
// A list of the extensions to check for implicit module loading and discovery, put the ni.dll in front of .dll to have higher priority to be loaded.
internal static string[] PSModuleExtensions = new string[] {
StringLiterals.PowerShellDataFileExtension,
StringLiterals.PowerShellModuleFileExtension,
StringLiterals.PowerShellCmdletizationFileExtension,
StringLiterals.WorkflowFileExtension,
".dll" };
StringLiterals.PowerShellNgenAssemblyExtension,
StringLiterals.DependentWorkflowAssemblyExtension};
/// <summary>
/// Returns true if the extension is one of the module extensions...
@ -519,7 +521,15 @@ namespace System.Management.Automation
internal static string GetModuleName(string path)
{
string fileName = path == null ? string.Empty : Path.GetFileName(path);
string ext = Path.GetExtension(fileName);
string ext;
if (fileName.EndsWith(StringLiterals.PowerShellNgenAssemblyExtension, StringComparison.OrdinalIgnoreCase))
{
ext = StringLiterals.PowerShellNgenAssemblyExtension;
}
else
{
ext = Path.GetExtension(fileName);
}
if (!string.IsNullOrEmpty(ext) && IsPowerShellModuleExtension(ext))
{
return fileName.Substring(0, fileName.Length - ext.Length);

View file

@ -141,7 +141,11 @@ namespace Microsoft.PowerShell.Commands
{
foreach (ModuleSpecification nestedModule in nestedModules)
{
if (!IsValidFilePath(nestedModule.Name, module, true) && !IsValidFilePath(nestedModule.Name + ".dll", module, true) && !IsValidFilePath(nestedModule.Name + ".psm1", module, true) && !IsValidGacAssembly(nestedModule.Name))
if (!IsValidFilePath(nestedModule.Name, module, true)
&& !IsValidFilePath(nestedModule.Name + StringLiterals.DependentWorkflowAssemblyExtension, module, true)
&& !IsValidFilePath(nestedModule.Name + StringLiterals.PowerShellNgenAssemblyExtension, module, true)
&& !IsValidFilePath(nestedModule.Name + StringLiterals.PowerShellModuleFileExtension, module, true)
&& !IsValidGacAssembly(nestedModule.Name))
{
// The nested module could be dependencies. We compare if it can be loaded by loadmanifest
bool isDependency = false;
@ -323,16 +327,23 @@ namespace Microsoft.PowerShell.Commands
{
string gacPath = System.Environment.GetEnvironmentVariable("windir") + "\\Microsoft.NET\\assembly";
string assemblyFile = assemblyName;
if (!assemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
string ngenAssemblyFile = assemblyName;
if (!assemblyName.EndsWith(StringLiterals.DependentWorkflowAssemblyExtension, StringComparison.OrdinalIgnoreCase))
{
assemblyFile = assemblyName + ".dll";
assemblyFile = assemblyName + StringLiterals.DependentWorkflowAssemblyExtension;
ngenAssemblyFile = assemblyName + StringLiterals.PowerShellNgenAssemblyExtension;
}
try
{
var allFiles = Directory.GetFiles(gacPath, assemblyFile, SearchOption.AllDirectories);
if (allFiles.Length == 0)
{
return false;
var allNgenFiles = Directory.GetFiles(gacPath, ngenAssemblyFile, SearchOption.AllDirectories);
if (allNgenFiles.Length == 0)
{
return false;
}
}
}
catch

View file

@ -138,6 +138,11 @@ namespace System.Management.Automation
/// </summary>
internal const string DependentWorkflowAssemblyExtension = ".dll";
/// <summary>
/// The file extension (including the dot) of an workflow dependent Ngen assembly
/// </summary>
internal const string PowerShellNgenAssemblyExtension = ".ni.dll";
internal const string PowerShellConsoleFileExtension = ".psc1";
/// <summary>

View file

@ -689,7 +689,7 @@ namespace System.Management.Automation.Runspaces
# WMI team fixed the formatting issue related to InstalledOn
# property in Windows7 (to return string)..so returning the WMI's
# version directly
[DateTime]::Parse($this.psBase.properties[""InstalledOn""].Value)
[DateTime]::Parse($this.psBase.properties[""InstalledOn""].Value, [System.Globalization.DateTimeFormatInfo]::new())
}
else
{
@ -1781,7 +1781,7 @@ namespace System.Management.Automation.Runspaces
# WMI team fixed the formatting issue related to InstalledOn
# property in Windows7 (to return string)..so returning the WMI's
# version directly
[DateTime]::Parse($this.psBase.CimInstanceProperties[""InstalledOn""].Value)
[DateTime]::Parse($this.psBase.CimInstanceProperties[""InstalledOn""].Value, [System.Globalization.DateTimeFormatInfo]::new())
}
else
{

View file

@ -7,6 +7,7 @@ using System.Linq;
using System.Threading;
using System.Management.Automation.Host;
using System.Management.Automation.Internal;
using Microsoft.PowerShell.Telemetry.Internal;
using Dbg = System.Management.Automation.Diagnostics;
#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings
@ -308,6 +309,16 @@ namespace System.Management.Automation.Runspaces
OpenHelper(syncCall);
if (etwEnabled) RunspaceEventSource.Log.OpenRunspaceStop();
// We report startup telemtry when opening the runspace - because this is the first time
// we are really using PowerShell. This isn't the cleanest place though, because
// sometimes there are many runspaces created - the callee ensures telemetry is only
// reported once. Note that if the host implements IHostProvidesTelemetryData, we rely
// on the host calling ReportStartupTelemetry.
if (!(this.Host is IHostProvidesTelemetryData))
{
TelemetryAPI.ReportStartupTelemetry(null);
}
}

View file

@ -16,6 +16,7 @@ using System.Diagnostics.CodeAnalysis; // for fxcop
using Dbg = System.Management.Automation.Diagnostics;
using System.Diagnostics;
using System.Linq;
using Microsoft.PowerShell.Telemetry.Internal;
#if CORECLR
@ -933,6 +934,28 @@ namespace System.Management.Automation.Runspaces
//Raise Event
RaiseRunspaceStateEvents ();
// Report telemetry if we have no more open runspaces.
bool allRunspacesClosed = true;
bool hostProvidesExitTelemetry = false;
foreach (var r in Runspace.RunspaceList)
{
if (r.RunspaceStateInfo.State != RunspaceState.Closed)
{
allRunspacesClosed = false;
break;
}
var localRunspace = r as LocalRunspace;
if (localRunspace != null && localRunspace.Host is IHostProvidesTelemetryData)
{
hostProvidesExitTelemetry = true;
break;
}
}
if (allRunspacesClosed && !hostProvidesExitTelemetry)
{
TelemetryAPI.ReportExitTelemetry(null);
}
}
/// <summary>

View file

@ -1109,6 +1109,8 @@ namespace System.Management.Automation.Host
/// </summary>
public void Dispose()
{
if (disposed) { return; }
// Wait for any pending output to be flushed to disk so that Stop-Transcript
// can be trusted to immediately have all content from that session in the file)
int outputWait = 0;
@ -1124,6 +1126,7 @@ namespace System.Management.Automation.Host
{
contentWriter.Flush();
contentWriter.Dispose();
contentWriter = null;
}
disposed = true;

View file

@ -584,7 +584,7 @@ namespace Microsoft.PowerShell.Commands
#region Overrides
/// <summary>
///
///
/// </summary>
protected override void ProcessRecord()
{
@ -739,6 +739,8 @@ namespace Microsoft.PowerShell.Commands
}
else
{
DISCUtils.ValidateRoleDefinitions(roleDefinitions);
result.Append(SessionConfigurationUtils.ConfigFragment(ConfigFileConstants.RoleDefinitions, RemotingErrorIdStrings.DISCRoleDefinitionsComment,
SessionConfigurationUtils.CombineHashtable(roleDefinitions, streamWriter), streamWriter, false));
}
@ -1055,6 +1057,10 @@ namespace Microsoft.PowerShell.Commands
}
}
#endregion
#region Private methods
private bool ShouldGenerateConfigurationSnippet(string parameterName)
{
return Full || MyInvocation.BoundParameters.ContainsKey(parameterName);
@ -1068,9 +1074,7 @@ namespace Microsoft.PowerShell.Commands
///
/// Creates a role capability file suitable for use in a Role Capability (which can be referenced in a Session Configuration file)
/// </summary>
#if !CORECLR
[Cmdlet(VerbsCommon.New, "PSRoleCapabilityFile", HelpUri = "http://go.microsoft.com/fwlink/?LinkId=623708")]
#endif
public class NewPSRoleCapabilityFileCommand : PSCmdlet
{
#region Parameters
@ -1745,6 +1749,8 @@ namespace Microsoft.PowerShell.Commands
#endregion
}
#region SessionConfigurationUtils
/// <summary>
/// Utility methods for configuration file commands
/// </summary>
@ -2029,4 +2035,6 @@ namespace Microsoft.PowerShell.Commands
return sb.ToString();
}
}
#endregion
}

View file

@ -2661,7 +2661,7 @@ namespace System.Management.Automation.Runspaces
var computeSystemPropertiesHandle = getComputeSystemPropertiesInfo.Invoke(null, new object[]{ ContainerId });
ContainerName = (string)computeSystemPropertiesType.GetProperty("Name").GetValue(computeSystemPropertiesHandle);
ContainerName = (string)computeSystemPropertiesType.GetProperty("SiloGuid").GetValue(computeSystemPropertiesHandle);
RuntimeId = (Guid)computeSystemPropertiesType.GetProperty("RuntimeId").GetValue(computeSystemPropertiesHandle);
}
catch (FileNotFoundException)

View file

@ -947,12 +947,6 @@ namespace System.Management.Automation.Remoting
internal static readonly string VisibleProviders = "VisibleProviders";
internal static readonly string VisibleExternalCommands = "VisibleExternalCommands";
// Keys that are not allowed in RoleDefinitions or a role capability
internal static HashSet<string> DisallowedRoleCapabilityKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
PowerShellVersion, SessionType, RoleDefinitions, LanguageMode, ExecutionPolicy
};
internal static ConfigTypeEntry[] ConfigFileKeys = new ConfigTypeEntry[] {
new ConfigTypeEntry(AliasDefinitions, new ConfigTypeEntry.TypeValidationCallback(AliasDefinitionsTypeValidationCallback)),
new ConfigTypeEntry(AssembliesToLoad, new ConfigTypeEntry.TypeValidationCallback(StringArrayTypeValidationCallback)),
@ -1366,13 +1360,41 @@ namespace System.Management.Automation.Remoting
}
}
#region DISC Utilities
/// <summary>
/// DISC utilities
/// </summary>
internal static class DISCUtils
{
#region Private data
internal static Type ExecutionPolicyType = null;
/// <summary>
/// !! NOTE that this list MUST be updated when new capability session configuration properties are added.
/// </summary>
private static readonly HashSet<string> AllowedRoleCapabilityKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"RoleCapabilities",
"ModulesToImport",
"VisibleAliases",
"VisibleCmdlets",
"VisibleFunctions",
"VisibleExternalCommands",
"VisibleProviders",
"ScriptsToProcess",
"AliasDefinitions",
"FunctionDefinitions",
"VariableDefinitions",
"EnvironmentVariables",
"TypesToProcess",
"FormatsToProcess",
"AssembliesToLoad"
};
#endregion
/// <summary>
/// Create an ExternalScriptInfo object from a file path.
/// </summary>
@ -1432,8 +1454,6 @@ namespace System.Management.Automation.Remoting
return result as Hashtable;
}
/// <summary>
/// Verifies the configuration hashtable
/// </summary>
@ -1606,8 +1626,68 @@ namespace System.Management.Automation.Remoting
}
}
}
/// <summary>
/// Validates Role Definition hash entries
///
/// RoleDefinitions = @{
/// 'Everyone' = @{
/// 'RoIeCapabilities' = 'Basic' };
/// 'Administrators' = @{
/// 'VisibleCmdlets' = 'Get-Process','Get-Location'; 'VisibleFunctions = 'TabExpansion2' } }
/// </summary>
/// <param name="roleDefinitions"></param>
internal static void ValidateRoleDefinitions(IDictionary roleDefinitions)
{
foreach (var roleKey in roleDefinitions.Keys)
{
if (!(roleKey is string))
{
var invalidOperationEx = new PSInvalidOperationException(
string.Format(RemotingErrorIdStrings.InvalidRoleKeyType, roleKey.GetType().FullName));
invalidOperationEx.SetErrorId("InvalidRoleKeyType");
throw invalidOperationEx;
}
//
// Each role capability in the role definition item should contain a hash table with allowed role capability key.
//
IDictionary roleDefinition = roleDefinitions[roleKey] as IDictionary;
if (roleDefinition == null)
{
var invalidOperationEx = new PSInvalidOperationException(
StringUtil.Format(RemotingErrorIdStrings.InvalidRoleValue, roleKey));
invalidOperationEx.SetErrorId("InvalidRoleEntryNotHashtable");
throw invalidOperationEx;
}
foreach (var key in roleDefinition.Keys)
{
// Ensure each role capability key is valid.
string roleCapabilityKey = key as string;
if (roleCapabilityKey == null)
{
var invalidOperationEx = new PSInvalidOperationException(
string.Format(RemotingErrorIdStrings.InvalidRoleCapabilityKeyType, key.GetType().FullName));
invalidOperationEx.SetErrorId("InvalidRoleCapabilityKeyType");
throw invalidOperationEx;
}
if (!AllowedRoleCapabilityKeys.Contains(roleCapabilityKey))
{
var invalidOperationEx = new PSInvalidOperationException(
string.Format(RemotingErrorIdStrings.InvalidRoleCapabilityKey, roleCapabilityKey));
invalidOperationEx.SetErrorId("InvalidRoleCapabilityKey");
throw invalidOperationEx;
}
}
}
}
}
#endregion
/// <summary>
/// Creates an initial session state based on the configuration language for PSSC files
/// </summary>
@ -1683,12 +1763,15 @@ namespace System.Management.Automation.Remoting
{
string message = StringUtil.Format(RemotingErrorIdStrings.InvalidRoleEntry, configHash["Roles"].GetType().FullName);
PSInvalidOperationException ioe = new PSInvalidOperationException(message);
ioe.SetErrorId("InvalidRoleEntryNotHashtable");
ioe.SetErrorId("InvalidRoleDefinitionNotHashtable");
throw ioe;
}
// Ensure that role definitions contain valid entries.
DISCUtils.ValidateRoleDefinitions(roleEntry);
// Go through the Roles hashtable
foreach(Object role in roleEntry.Keys)
foreach (Object role in roleEntry.Keys)
{
// Check if this role applies to the connected user
if (roleVerifier(role.ToString()))
@ -1744,13 +1827,6 @@ namespace System.Management.Automation.Remoting
foreach (Object customization in childConfigHash.Keys)
{
string customizationString = customization.ToString();
if (ConfigFileConstants.DisallowedRoleCapabilityKeys.Contains(customizationString))
{
string message = StringUtil.Format(RemotingErrorIdStrings.InvalidRoleCapabilityKey, customizationString);
PSInvalidOperationException ioe = new PSInvalidOperationException(message);
ioe.SetErrorId("InvalidRoleTookitKey");
throw ioe;
}
ArrayList customizationValue = new ArrayList();

View file

@ -323,11 +323,14 @@ namespace System.Management.Automation.Remoting
{
if (_serverDriverRemoteHost.PropagatePop)
{
// Optionally forward the PopRunspace command to client.
// Forward the PopRunspace command to client and keep *this* pushed runspace as
// the configured JEA restricted session.
_serverMethodExecutor.ExecuteVoidMethod(RemoteHostMethodId.PopRunspace);
}
_serverDriverRemoteHost.PopRunspace();
else
{
_serverDriverRemoteHost.PopRunspace();
}
}
else
{

View file

@ -515,8 +515,6 @@ namespace System.Management.Automation
// Let exceptions propagate.
RemoteRunspace remoteRunspace = HostUtilities.CreateConfiguredRunspace(this.configurationName, this.remoteHost);
// Ensure session ends and configured runspace is closed on pop.
remoteRunspace.ShouldCloseOnPop = true;
this.remoteHost.AllowPushRunspace = true;
this.remoteHost.PropagatePop = true;
@ -665,7 +663,9 @@ namespace System.Management.Automation
args.Runspace.ExecutionContext.LanguageMode = PSLanguageMode.ConstrainedLanguage;
}
// Set the current location to Personal folder for this runspace.
// Set the current location to MyDocuments folder for this runspace.
// This used to be set to the Personal folder but was changed to MyDocuments folder for
// compatibility with PowerShell on Nano Server for PowerShell V5.
// This is needed because in the remoting scenario, Environment.CurrentDirectory
// always points to System Folder (%windir%\system32) irrespective of the
// user as %HOMEDRIVE% and %HOMEPATH% are not available for the logon process.
@ -676,17 +676,12 @@ namespace System.Management.Automation
string personalfolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
args.Runspace.ExecutionContext.EngineSessionState.SetLocation(personalfolder);
}
catch (ArgumentException)
{
}
catch (ProviderNotFoundException)
{
}
catch (DriveNotFoundException)
{
}
catch (ProviderInvocationException)
catch (Exception e)
{
// SetLocation API can call 3rd party code and so there is no telling what exception may be thrown.
// Setting location is not critical and is expected not to work with some account types, so we want
// to ignore all but critical errors.
CommandProcessorBase.CheckForSevereException(e);
}
// Run startup scripts
@ -875,6 +870,7 @@ namespace System.Management.Automation
StartPowerShellCommandOnPushedRunspace(
powershell,
null,
data.PowerShellId,
data.RunspacePoolId,
hostInfo,
@ -1085,23 +1081,41 @@ namespace System.Management.Automation
"Name", "Namespace", "HelpUri", "CommandType", "ResolvedCommandName", "OutputType", "Parameters" });
HostInfo useRunspaceHost = new HostInfo(null);
useRunspaceHost.UseRunspaceHost = true;
ServerPowerShellDriver driver = new ServerPowerShellDriver(
countingPipeline,
mainPipeline,
true /* no input */,
data.PowerShellId,
data.RunspacePoolId,
this,
#if !CORECLR // No ApartmentState In CoreCLR
ApartmentState.Unknown,
#endif
useRunspaceHost,
0 /* stream options */,
false /* addToHistory */,
null /* use default rsPool runspace */);
useRunspaceHost.UseRunspaceHost = true;
driver.Start();
if (remoteHost.IsRunspacePushed)
{
// If we have a pushed runspace then execute there.
StartPowerShellCommandOnPushedRunspace(
countingPipeline,
mainPipeline,
data.PowerShellId,
data.RunspacePoolId,
useRunspaceHost,
0,
true,
false);
}
else
{
// Run on usual driver.
ServerPowerShellDriver driver = new ServerPowerShellDriver(
countingPipeline,
mainPipeline,
true /* no input */,
data.PowerShellId,
data.RunspacePoolId,
this,
#if !CORECLR // No ApartmentState In CoreCLR
ApartmentState.Unknown,
#endif
useRunspaceHost,
0 /* stream options */,
false /* addToHistory */,
null /* use default rsPool runspace */);
driver.Start();
}
}
/// <summary>
@ -1206,6 +1220,7 @@ namespace System.Management.Automation
/// Starts the PowerShell command on the currently pushed Runspace
/// </summary>
/// <param name="powershell">PowerShell command or script</param>
/// <param name="extraPowerShell">PowerShell command to run after first completes</param>
/// <param name="powershellId">PowerShell Id</param>
/// <param name="runspacePoolId">RunspacePool Id</param>
/// <param name="hostInfo">Host Info</param>
@ -1214,6 +1229,7 @@ namespace System.Management.Automation
/// <param name="addToHistory">Add to history</param>
private void StartPowerShellCommandOnPushedRunspace(
PowerShell powershell,
PowerShell extraPowerShell,
Guid powershellId,
Guid runspacePoolId,
HostInfo hostInfo,
@ -1225,7 +1241,7 @@ namespace System.Management.Automation
ServerPowerShellDriver driver = new ServerPowerShellDriver(
powershell,
null,
extraPowerShell,
noInput,
powershellId,
runspacePoolId,

View file

@ -1053,29 +1053,41 @@ namespace System.Management.Automation.Remoting
if (onConnect)
{
// Win10 server can support Win8 client
if (clientProtocolVersion == RemotingConstants.ProtocolVersionWin8RTM &&
(
(serverProtocolVersion == RemotingConstants.ProtocolVersionWin10RTM)
))
bool connectSupported = false;
// Win10 server can support reconstruct/reconnect for all 2.x protocol versions
// that support reconstruct/reconnect, Protocol 2.2+
// Major protocol version differences (2.x -> 3.x) are not supported.
if ((serverProtocolVersion == RemotingConstants.ProtocolVersionWin10RTM) &&
(clientProtocolVersion.Major == serverProtocolVersion.Major))
{
// - report that server is Win8 version to the client
serverProtocolVersion = RemotingConstants.ProtocolVersionWin8RTM;
_context.ServerCapability.ProtocolVersion = serverProtocolVersion;
}
else
{
// All other version mismatches, throw an error.
if (clientProtocolVersion != serverProtocolVersion)
if (clientProtocolVersion.Minor == RemotingConstants.ProtocolVersionWin8RTM.Minor)
{
PSRemotingDataStructureException reasonOfFailure =
new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnNegotiation,
RemoteDataNameStrings.PS_STARTUP_PROTOCOL_VERSION_NAME,
clientProtocolVersion,
PSVersionInfo.BuildVersion,
RemotingConstants.ProtocolVersion);
throw reasonOfFailure;
// Report that server is Win8 version to the client
// Protocol: 2.2
connectSupported = true;
serverProtocolVersion = RemotingConstants.ProtocolVersionWin8RTM;
_context.ServerCapability.ProtocolVersion = serverProtocolVersion;
}
else if (clientProtocolVersion.Minor > RemotingConstants.ProtocolVersionWin8RTM.Minor)
{
// All other minor versions are supported and the server returns its full capability
// Protocol: 2.3, 2.4, 2.5 ...
connectSupported = true;
}
}
if (!connectSupported)
{
// Throw for protocol versions 2.x that don't support disconnect/reconnect.
// Protocol: < 2.2
PSRemotingDataStructureException reasonOfFailure =
new PSRemotingDataStructureException(RemotingErrorIdStrings.ServerConnectFailedOnNegotiation,
RemoteDataNameStrings.PS_STARTUP_PROTOCOL_VERSION_NAME,
clientProtocolVersion,
PSVersionInfo.BuildVersion,
RemotingConstants.ProtocolVersion);
throw reasonOfFailure;
}
}
else

View file

@ -22,6 +22,7 @@ using System.Text;
using Microsoft.Win32;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.PowerShell.Telemetry.Internal;
#if CORECLR
// Use stub for Serializable attribute and ISerializable related types
@ -63,6 +64,8 @@ namespace System.Management.Automation
internal bool Compile(bool optimized)
{
var sw = new Stopwatch();
sw.Start();
if (_attributes == null)
{
InitializeMetadata();
@ -86,6 +89,9 @@ namespace System.Management.Automation
CompileOptimized();
}
sw.Stop();
TelemetryAPI.ReportScriptTelemetry((Ast)_ast, !optimized, sw.ElapsedMilliseconds);
return optimized;
}

View file

@ -7,6 +7,7 @@ using System.Linq;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management.Automation;
using System.Globalization;
using System.Management.Automation.Internal;
@ -306,6 +307,9 @@ namespace Microsoft.PowerShell.Commands
private GraphicalHostReflectionWrapper graphicalHostReflectionWrapper;
#endif
private readonly Stopwatch _timer = new Stopwatch();
private bool _updatedHelp;
#endregion
#region Cmdlet API implementation
@ -315,11 +319,14 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
protected override void BeginProcessing()
{
_timer.Start();
if (!Online.IsPresent && UpdatableHelpSystem.ShouldPromptToUpdateHelp() && HostUtilities.IsProcessInteractive(MyInvocation) && HasInternetConnection())
{
if(ShouldContinue(HelpDisplayStrings.UpdateHelpPromptBody, HelpDisplayStrings.UpdateHelpPromptTitle))
{
System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace).AddCommand("Update-Help").Invoke();
_updatedHelp = true;
}
UpdatableHelpSystem.SetDisablePromptToUpdateHelp();
@ -397,6 +404,11 @@ namespace Microsoft.PowerShell.Commands
countOfHelpInfos++;
}
_timer.Stop();
if (!string.IsNullOrEmpty(Name))
Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI.ReportGetHelpTelemetry(Name, countOfHelpInfos, _timer.ElapsedMilliseconds, _updatedHelp);
// Write full help as there is only one help info object
if (1 == countOfHelpInfos)
{

View file

@ -172,7 +172,7 @@ namespace System.Management.Automation
XmlElement parameterValue = doc.CreateElement("command:parameterValue", commandURI);
parameterValue.SetAttribute("required", isSwitchParameter ? "false" : "true");
//parameterValue.SetAttribute("variableLength", "unknown");
XmlText parameterValue_text = doc.CreateTextNode(elementType.Name);
XmlText parameterValue_text = doc.CreateTextNode(type.Name);
command_parameter.AppendChild(parameterValue).AppendChild(parameterValue_text);
}
}

View file

@ -1071,9 +1071,6 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
<data name="InvalidRoleEntry" xml:space="preserve">
<value>The 'Roles' entry must be a hashtable, but was a {0}.</value>
</data>
<data name="InvalidRoleCapabilityKey" xml:space="preserve">
<value>The key '{0}' is not valid in a role capability or role definition.</value>
</data>
<data name="InvalidRoleValue" xml:space="preserve">
<value>Could not convert the value of the '{0}' role entry to a hashtable. The 'Roles' entry must be a hashtable with group names for keys, where the value associated with each key is another hashtable of session configuration properties for that role.</value>
</data>
@ -1599,4 +1596,13 @@ All WinRM sessions connected to Windows PowerShell session configurations, such
<data name="InvalidUserDriveName" xml:space="preserve">
<value>Cannot create a session User Drive because the current user name contains invalid file path characters.</value>
</data>
<data name="InvalidRoleCapabilityKey" xml:space="preserve">
<value>Invalid role capability key: {0}. Make sure the role capability name is spelled correctly and is a valid session configuration property.</value>
</data>
<data name="InvalidRoleCapabilityKeyType" xml:space="preserve">
<value>Invalid role capability key type: {0}. Role capability keys must be strings that identify a valid session configuration property.</value>
</data>
<data name="InvalidRoleKeyType" xml:space="preserve">
<value>Invalid role key type: {0}. Role keys must be strings that identify a security group.</value>
</data>
</root>

View file

@ -2144,8 +2144,44 @@ namespace System.Management.Automation.Security
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr CryptCATStoreFromHandle(
IntPtr hCatalog
);
);
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
internal static extern bool CryptCATAdminAcquireContext2(
ref IntPtr phCatAdmin,
IntPtr pgSubsystem,
[MarshalAs(UnmanagedType.LPWStr)]
string pwszHashAlgorithm,
IntPtr pStrongHashPolicy,
DWORD dwFlags
);
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
internal static extern bool CryptCATAdminReleaseContext(
IntPtr phCatAdmin,
DWORD dwFlags
);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern unsafe IntPtr CreateFile(
string lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
DWORD lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("wintrust.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool CryptCATAdminCalcHashFromFileHandle2(
IntPtr hCatAdmin,
IntPtr hFile,
[In, Out] ref DWORD pcbHash,
IntPtr pbHash,
DWORD dwFlags
);
[DllImport("wintrust.dll", CharSet = CharSet.Unicode)]
internal static extern IntPtr CryptCATEnumerateMember(
IntPtr hCatalog,

View file

@ -479,6 +479,7 @@ namespace System.Management.Automation
{
uint zoneId;
object curSecMgr = null;
const UInt32 MUTZ_DONT_USE_CACHE = 0x00001000;
int hr = NativeMethods.CoInternetCreateSecurityManager(null, out curSecMgr, 0);
if (hr != NativeMethods.S_OK)
@ -490,7 +491,7 @@ namespace System.Management.Automation
try
{
NativeMethods.IInternetSecurityManager ism = (NativeMethods.IInternetSecurityManager)curSecMgr;
hr = ism.MapUrlToZone(filePath, out zoneId, 0);
hr = ism.MapUrlToZone(filePath, out zoneId, MUTZ_DONT_USE_CACHE);
if (hr == NativeMethods.S_OK)
{
SecurityZone result;

View file

@ -3,10 +3,21 @@ Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management.Automation.Internal;
using System.Diagnostics.CodeAnalysis;
using System.Management.Automation;
using System.Management.Automation.Language;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.PowerShell.Telemetry.Internal;
#if CORECLR
using Environment = System.Management.Automation.Environment;
#else
using Environment = System.Environment;
#endif
namespace Microsoft.PowerShell.Telemetry.Internal
{
@ -15,7 +26,7 @@ namespace Microsoft.PowerShell.Telemetry.Internal
[SuppressMessage("Microsoft.MSInternal", "CA903:InternalNamespaceShouldNotContainPublicTypes")]
public static class TelemetryAPI
{
#region Public API
#region Public API
/// <summary>
/// Public API to expose Telemetry in PowerShell
@ -27,6 +38,369 @@ namespace Microsoft.PowerShell.Telemetry.Internal
TelemetryWrapper.TraceMessage(message, arguments);
}
#endregion
#endregion
static int anyPowerShellSessionOpen;
static DateTime sessionStartTime;
enum HostIsInteractive
{
Unknown,
Iteractive,
NonInteractive
}
/// <summary>
/// Called either after opening a runspace (the default), or by the host application.
/// </summary>
public static void ReportStartupTelemetry(IHostProvidesTelemetryData ihptd)
{
// Avoid reporting startup more than once, except if we report "exited" and
// another runspace gets opened.
if (Interlocked.CompareExchange(ref anyPowerShellSessionOpen, 1, 0) == 1)
return;
bool is32Bit;
#if CORECLR
is32Bit = IntPtr.Size == 4;
#else
is32Bit = !Environment.Is64BitProcess;
#endif
var psversion = PSVersionInfo.PSVersion.ToString();
var hostName = Process.GetCurrentProcess().ProcessName;
if (ihptd != null)
{
TelemetryWrapper.TraceMessage("PSHostStart", new
{
Interactive = ihptd.HostIsInteractive ? HostIsInteractive.Iteractive : HostIsInteractive.NonInteractive,
ProfileLoadTime = ihptd.ProfileLoadTimeInMS,
ReadyForInputTime = ihptd.ReadyForInputTimeInMS,
Is32Bit = is32Bit,
PSVersion = psversion,
ProcessName = hostName,
});
}
else
{
TelemetryWrapper.TraceMessage("PSHostStart", new
{
Interactive = HostIsInteractive.Unknown,
ProfileLoadTime = 0,
ReadyForInputTime = 0,
Is32Bit = is32Bit,
PSVersion = psversion,
ProcessName = hostName,
});
}
sessionStartTime = DateTime.Now;
}
/// <summary>
/// Called after there are no more open runspaces. In some host applications, this could
/// report multiple exits.
/// </summary>
public static void ReportExitTelemetry(IHostProvidesTelemetryData ihptd)
{
TelemetryWrapper.TraceMessage("PSHostStop", new
{
InteractiveCommandCount = ihptd != null ? ihptd.InteractiveCommandCount : 0,
TabCompletionTimes = tabCompletionTimes,
TabCompletionCounts = tabCompletionCounts,
TabCompletionResultCounts = tabCompletionResultCounts,
SessionTime = (DateTime.Now - sessionStartTime).TotalMilliseconds
});
// In case a host opens another runspace, we will want another PSHostStart event,
// so reset our flag here to allow that event to fire.
anyPowerShellSessionOpen = 0;
}
/// <summary>
/// Report Get-Help requests, how many results are returned, and how long it took.
/// </summary>
internal static void ReportGetHelpTelemetry(string name, int topicsFound, long timeInMS, bool updatedHelp)
{
TelemetryWrapper.TraceMessage("PSHelpRequest", new
{
TopicCount = topicsFound,
TimeInMS = timeInMS,
RanUpdateHelp = updatedHelp,
HelpTopic = name,
});
}
/// <summary>
/// Report when Get-Command fails to find something.
/// </summary>
internal static void ReportGetCommandFailed(string[] name, long timeInMS)
{
TelemetryWrapper.TraceMessage("PSGetCommandFailed", new { TimeInMS = timeInMS, CommandNames = name });
}
private static long[] tabCompletionTimes = new long[(int)CompletionResultType.DynamicKeyword + 1];
private static int[] tabCompletionCounts = new int[(int)CompletionResultType.DynamicKeyword + 1];
private static int[] tabCompletionResultCounts = new int[(int)CompletionResultType.DynamicKeyword + 1];
internal static void ReportTabCompletionTelemetry(long elapsedMilliseconds, int count, CompletionResultType completionResultType)
{
// We'll collect some general statistics.
int idx = (int)completionResultType;
if (idx >= 0 && idx <= (int)CompletionResultType.DynamicKeyword)
{
tabCompletionTimes[idx] += elapsedMilliseconds;
tabCompletionCounts[idx]++;
tabCompletionResultCounts[idx] += count;
}
// Also write an event for any slow tab completion (> 250ms).
if (elapsedMilliseconds > 250)
{
TelemetryWrapper.TraceMessage("PSSlowTabCompletion", new {
Time = elapsedMilliseconds,
Count = count,
Type = completionResultType,
});
}
}
/// <summary>
/// Report that a module was loaded, but only do so for modules that *might* be authored by Microsoft. We can't
/// be 100% certain, but we'll ignore non-Microsoft module names when looking at any data, so it's best to
/// at least attempt avoiding collecting data we'll ignore.
/// </summary>
internal static void ReportModuleLoad(PSModuleInfo foundModule)
{
var modulePath = foundModule.Path;
var companyName = foundModule.CompanyName;
bool couldBeMicrosoftModule =
(modulePath != null &&
(modulePath.StartsWith(Utils.GetApplicationBase(Utils.DefaultPowerShellShellID), StringComparison.OrdinalIgnoreCase) ||
// The following covers both 64 and 32 bit Program Files by assuming 32bit is just ...\Program Files + " (x86)"
modulePath.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), StringComparison.OrdinalIgnoreCase))) ||
(companyName != null &&
foundModule.CompanyName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase));
if (couldBeMicrosoftModule)
{
TelemetryWrapper.TraceMessage("PSImportModule", new
{
ModuleName = foundModule.Name,
Version = foundModule.Version.ToString()
});
}
}
enum ScriptFileType
{
None = 0,
Ps1 = 1,
Psd1 = 2,
Psm1 = 3,
Other = 4,
}
private static readonly int promptHashCode = "prompt".GetHashCode();
/// <summary>
/// Report some telemetry about the scripts that are run
/// </summary>
internal static void ReportScriptTelemetry(Ast ast, bool dotSourced, long compileTimeInMS)
{
if (ast.Parent != null || !TelemetryWrapper.IsEnabled)
return;
Task.Run(() =>
{
var extent = ast.Extent;
var text = extent.Text;
var hash = text.GetHashCode();
// Ignore 'prompt' so we don't generate an event for every 'prompt' that is invoked.
// (We really should only create 'prompt' once, but we don't.
if (hash == promptHashCode)
return;
var visitor = new ScriptBlockTelemetry();
ast.Visit(visitor);
var scriptFileType = ScriptFileType.None;
var fileName = extent.File;
if (fileName != null)
{
var ext = System.IO.Path.GetExtension(fileName);
if (".ps1".Equals(ext, StringComparison.OrdinalIgnoreCase))
{
scriptFileType = ScriptFileType.Ps1;
}
else if (".psd1".Equals(ext, StringComparison.OrdinalIgnoreCase))
{
scriptFileType = ScriptFileType.Psd1;
}
else if (".psm1".Equals(ext, StringComparison.OrdinalIgnoreCase))
{
scriptFileType = ScriptFileType.Psm1;
}
else
{
// Reachable?
scriptFileType = ScriptFileType.Other;
}
}
TelemetryWrapper.TraceMessage("PSScriptDetails", new
{
Hash = hash,
IsDotSourced = dotSourced,
ScriptFileType = scriptFileType,
Length = text.Length,
LineCount = extent.EndLineNumber - extent.StartLineNumber,
CompileTimeInMS = compileTimeInMS,
StatementCount = visitor.StatementCount,
CountOfCommands = visitor.CountOfCommands,
CountOfDotSourcedCommands = visitor.CountOfDotSourcedCommands,
MaxArrayLength = visitor.MaxArraySize,
ArrayLiteralCount = visitor.ArrayLiteralCount,
ArrayLiteralCumulativeSize = visitor.ArrayLiteralCumulativeSize,
MaxStringLength = visitor.MaxStringSize,
StringLiteralCount = visitor.StringLiteralCount,
StringLiteralCumulativeSize = visitor.StringLiteralCumulativeSize,
MaxPipelineDepth = visitor.MaxPipelineDepth,
PipelineCount = visitor.PipelineCount,
FunctionCount = visitor.FunctionCount,
ScriptBlockCount = visitor.ScriptBlockCount,
ClassCount = visitor.ClassCount,
EnumCount = visitor.EnumCount,
CommandsCalled = visitor.CommandsCalled,
});
});
}
}
}
class ScriptBlockTelemetry : AstVisitor2
{
internal ScriptBlockTelemetry()
{
CommandsCalled = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
}
internal Dictionary<string, int> CommandsCalled { get; private set; }
internal int CountOfCommands { get; private set; }
internal int CountOfDotSourcedCommands { get; private set; }
public override AstVisitAction VisitCommand(CommandAst commandAst)
{
CountOfCommands++;
var commandName = commandAst.GetCommandName();
if (commandName != null)
{
int commandCount;
CommandsCalled.TryGetValue(commandName, out commandCount);
CommandsCalled[commandName] = commandCount + 1;
}
if (commandAst.InvocationOperator == TokenKind.Dot)
CountOfDotSourcedCommands++;
return AstVisitAction.Continue;
}
internal int MaxStringSize { get; private set; }
internal int StringLiteralCount { get; private set; }
internal int StringLiteralCumulativeSize { get; private set; }
public override AstVisitAction VisitStringConstantExpression(StringConstantExpressionAst stringConstantExpressionAst)
{
var stringSize = stringConstantExpressionAst.Value.Length;
StringLiteralCount += 1;
StringLiteralCumulativeSize += stringSize;
MaxStringSize = Math.Max(MaxStringSize, stringSize);
return AstVisitAction.Continue;
}
public override AstVisitAction VisitExpandableStringExpression(ExpandableStringExpressionAst expandableStringExpressionAst)
{
var stringSize = expandableStringExpressionAst.Value.Length;
StringLiteralCount += 1;
StringLiteralCumulativeSize += stringSize;
MaxStringSize = Math.Max(MaxStringSize, stringSize);
return AstVisitAction.Continue;
}
internal int MaxArraySize { get; private set; }
internal int ArrayLiteralCount { get; private set; }
internal int ArrayLiteralCumulativeSize { get; private set; }
public override AstVisitAction VisitArrayLiteral(ArrayLiteralAst arrayLiteralAst)
{
var elementCount = arrayLiteralAst.Elements.Count;
ArrayLiteralCount += 1;
ArrayLiteralCumulativeSize += elementCount;
MaxArraySize = Math.Max(MaxArraySize, elementCount);
return AstVisitAction.Continue;
}
internal int StatementCount { get; private set; }
public override AstVisitAction VisitBlockStatement(BlockStatementAst blockStatementAst)
{
StatementCount += blockStatementAst.Body.Statements.Count;
return AstVisitAction.Continue;
}
public override AstVisitAction VisitNamedBlock(NamedBlockAst namedBlockAst)
{
StatementCount += namedBlockAst.Statements.Count;
return AstVisitAction.Continue;
}
internal int FunctionCount { get; private set; }
public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst)
{
FunctionCount += 1;
return AstVisitAction.Continue;
}
internal int ScriptBlockCount { get; private set; }
public override AstVisitAction VisitScriptBlockExpression(ScriptBlockExpressionAst scriptBlockExpressionAst)
{
ScriptBlockCount += 1;
return AstVisitAction.Continue;
}
internal int MaxPipelineDepth { get; private set; }
internal int PipelineCount { get; private set; }
public override AstVisitAction VisitPipeline(PipelineAst pipelineAst)
{
MaxPipelineDepth = Math.Max(MaxPipelineDepth, pipelineAst.PipelineElements.Count);
PipelineCount += 1;
return AstVisitAction.Continue;
}
internal int ClassCount { get; private set; }
internal int EnumCount { get; private set; }
public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
{
if (typeDefinitionAst.IsClass)
ClassCount += 1;
else if (typeDefinitionAst.IsEnum)
EnumCount += 1;
return AstVisitAction.Continue;
}
}
/// <summary>
/// If implemented by the host, the host should call <see cref="TelemetryAPI.ReportStartupTelemetry"/> and <see cref="TelemetryAPI.ReportExitTelemetry"/>
/// and track the data defined by this interface.
/// </summary>
public interface IHostProvidesTelemetryData
{
/// <summary>A host sets this property as appropriate - used when reporting telemetry.</summary>
bool HostIsInteractive { get; }
/// <summary>A host sets this property as appropriate - used when reporting telemetry.</summary>
double ProfileLoadTimeInMS { get; }
/// <summary>A host sets this property as appropriate - used when reporting telemetry.</summary>
double ReadyForInputTimeInMS { get; }
/// <summary>A host sets this property as appropriate - used when reporting telemetry.</summary>
int InteractiveCommandCount { get; }
}
}

View file

@ -44,10 +44,10 @@ namespace System.Management.Automation.Internal
const int EtwSelfDescribingEventFormat = 8;
var eventSourceSettingsEnumObject = Enum.ToObject(eventSourceSettingsType, EtwSelfDescribingEventFormat);
// Create instance of the class EventSource with Provider name of "Microsoft.Windows.PowerShell"
// Create instance of the class EventSource with Provider name of "Microsoft-PowerShell-Telemetry"
// Supply this eventSourceTrait to EventSource constructor to enable Asimov type events
var eventSource = (EventSource)Activator.CreateInstance(typeof(EventSource),
new object[] {"Microsoft.Windows.PowerShell",
new object[] {"Microsoft-PowerShell-Telemetry",
eventSourceSettingsEnumObject,
new[] { "ETW_GROUP", "{4f50731a-89cf-4782-b3e0-dce8c90476ba}" }});