Update files from Source Depot changeset [SD:700586]
Corresponds to 84837459913bb00660964d19ea07f5e0c7b4b442 in psl-monad.
This commit is contained in:
parent
a7ba3395b9
commit
3998ce06ba
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -133,13 +133,13 @@
|
|||
<value>PowerShell[.exe] [-PSConsoleFile <file> | -Version <version>]
|
||||
[-NoLogo] [-NoExit] [-NoProfile] [-NonInteractive] [-STA]
|
||||
[-OutputFormat {Text | XML}] [-InputFormat {Text | XML}]
|
||||
[-ConfigurationName <string>]
|
||||
[-File fileName [arguments...]] [-ExecutionPolicy <ExecutionPolicy>]
|
||||
[-Command { - | <script-block> [-args <arg-array>]
|
||||
| <string> [<CommandParameters>] } ]
|
||||
[-File fileName [arguments...]] [-ExecutionPolicy <ExecutionPolicy>]
|
||||
|
||||
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 "& {Get-EventLog -LogName security}"
|
||||
</value>
|
||||
|
|
|
@ -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>
|
|
@ -124,8 +124,9 @@ Copyright (C) 2016 Microsoft Corporation. All rights reserved.</value>
|
|||
<data name="ShellHelp" xml:space="preserve">
|
||||
<value>PowerShell[.exe] [-PSConsoleFile <file> | -Version <version>]
|
||||
[-NoLogo] [-NoExit] [-Sta] [-Mta] [-NoProfile] [-NonInteractive]
|
||||
[-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
|
||||
[-WindowStyle <style>] [-EncodedCommand <Base64EncodedCommand>]
|
||||
[-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
|
||||
[-WindowStyle <style>] [-EncodedCommand <Base64EncodedCommand>]
|
||||
[-ConfigurationName <string>]
|
||||
[-File <filePath> <args>] [-ExecutionPolicy <ExecutionPolicy>]
|
||||
[-Command { - | <script-block> [-args <arg-array>]
|
||||
| <string> [<CommandParameters>] } ]
|
||||
|
@ -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 "& {Get-EventLog -LogName security}"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}" }});
|
||||
|
||||
|
|
Loading…
Reference in a new issue