2016-03-30 23:20:52 +02:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +
Copyright ( c ) Microsoft Corporation . All rights reserved .
- - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
using System.Collections ;
using System.Collections.Concurrent ;
using System.Collections.Generic ;
using System.Collections.ObjectModel ;
using System.Diagnostics.CodeAnalysis ;
using System.Diagnostics.Tracing ;
using System.IO ;
using System.Linq ;
using System.Management.Automation.Internal ;
using System.Management.Automation.Provider ;
using System.Management.Automation.Language ;
using System.Reflection ;
using System.Threading ;
using Microsoft.PowerShell.Commands ;
using Debug = System . Management . Automation . Diagnostics ;
using System.Management.Automation.Host ;
using System.Text ;
using System.Threading.Tasks ;
namespace System.Management.Automation.Runspaces
{
internal class EarlyStartup
{
internal static void Init ( )
{
// Code added here should:
// * run every time we start PowerSHell
// * have high CPU cost
// * be ordered from most expensive to least expensive, or at least needed earliest
// * this method should return quickly, so all work should be run in one or more tasks.
// * code called from here should correctly handle being called twice, in case initialization
// is needed in the main code path before the task completes.
//
// Code added here should not:
// * count on running - not all hosts will call this method
// * have high disk cost
// We shouldn't create too many tasks.
// This task takes awhile, so it gets it's own task
Task . Run ( ( ) = >
{
// Building the catalog is expensive, so force that to happen early on a background thread, and do so
// on a file we are very likely to read anyway.
var pshome = Utils . GetApplicationBase ( Utils . DefaultPowerShellShellID ) ;
var unused = SecuritySupport . IsProductBinary ( Path . Combine ( pshome , "Modules" , "Microsoft.PowerShell.Utility" , "Microsoft.PowerShell.Utility.psm1" ) ) ;
} ) ;
// One other task for other stuff that's faster, but still a little slow.
Task . Run ( ( ) = >
{
// Loading the resources for System.Management.Automation can be expensive, so force that to
// happen early on a background thread.
var unused0 = RunspaceInit . OutputEncodingDescription ;
// Amsi initialize can also be a little slow
2016-05-02 21:49:27 +02:00
if ( Platform . IsWindows )
{
AmsiUtils . Init ( ) ;
}
2016-03-30 23:20:52 +02:00
// This will init some tables and could load some assemblies.
var unused1 = TypeAccelerators . builtinTypeAccelerators ;
// This will init some tables and could load some assemblies.
var unused2 = LanguagePrimitives . GetEnumerator ( null ) ;
} ) ;
}
}
/// <summary>
/// Baseclass for defining elements that can be added
/// to an InitialSessionState object.
/// </summary>
public abstract class InitialSessionStateEntry
{
/// <summary>
/// ctor so that each derived class has a name
/// </summary>
/// <param name="name"></param>
protected InitialSessionStateEntry ( string name )
{
2016-08-02 22:29:09 +02:00
Name = name ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// The name of this entry
/// </summary>
2016-08-02 22:29:09 +02:00
public string Name { get ; internal set ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The SnapIn to load from initially
/// </summary>
2016-08-02 22:29:09 +02:00
public PSSnapInInfo PSSnapIn { get ; private set ; }
2016-03-30 23:20:52 +02:00
internal void SetPSSnapIn ( PSSnapInInfo psSnapIn )
{
2016-08-02 22:29:09 +02:00
PSSnapIn = psSnapIn ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// The SnapIn to load from initially
/// </summary>
2016-08-02 22:29:09 +02:00
public PSModuleInfo Module { get ; private set ; }
2016-03-30 23:20:52 +02:00
internal void SetModule ( PSModuleInfo module )
{
2016-08-02 22:29:09 +02:00
Module = module ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object
/// </summary>
/// <returns>The cloned object...</returns>
public abstract InitialSessionStateEntry Clone ( ) ;
}
/// <summary>
/// Class to constrain session state entries
/// </summary>
public abstract class ConstrainedSessionStateEntry : InitialSessionStateEntry
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="visibility"></param>
protected ConstrainedSessionStateEntry ( string name , SessionStateEntryVisibility visibility )
: base ( name )
{
2016-08-02 22:29:09 +02:00
Visibility = visibility ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
2016-08-02 22:29:09 +02:00
public SessionStateEntryVisibility Visibility { get ; set ; }
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Command class so that all the commands can derive off this one.
/// Adds the flexibility of adding addditional derived class,
/// such as ProxyCommand for Exchange.
/// Derived classes - Alias, Application, Cmdlet, Function, Script.
/// </summary>
public abstract class SessionStateCommandEntry : ConstrainedSessionStateEntry
{
/// <summary>
/// Base constructor for all SessionState commands.
/// </summary>
/// <param name="name"></param>
protected SessionStateCommandEntry ( string name )
: base ( name , SessionStateEntryVisibility . Public )
{
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="visibility"></param>
protected internal SessionStateCommandEntry ( string name , SessionStateEntryVisibility visibility )
: base ( name , visibility )
{
}
/// <summary>
/// Returns the type of the command using an enum
/// instead of requiring a full reflection type check.
/// </summary>
2016-08-02 22:29:09 +02:00
public CommandTypes CommandType { get ; internal set ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// Is internal so it can be set by the engine code...
/// This is used to specify whether this command was imported or not
/// If noClobber is specified during Import-Module, it is set to false
/// </summary>
internal bool _isImported = true ;
}
/// <summary>
/// Type file configuration entry...
/// </summary>
public sealed class SessionStateTypeEntry : InitialSessionStateEntry
{
/// <summary>
/// Loads all entries from the types file.
/// </summary>
/// <param name="fileName"></param>
public SessionStateTypeEntry ( string fileName )
: base ( fileName )
{
if ( String . IsNullOrEmpty ( fileName ) | | fileName . Trim ( ) . Length = = 0 )
{
throw PSTraceSource . NewArgumentException ( "fileName" ) ;
}
2016-08-02 22:29:09 +02:00
FileName = fileName . Trim ( ) ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Loads all the types specified in the typeTable
/// </summary>
/// <param name="typeTable"></param>
public SessionStateTypeEntry ( TypeTable typeTable )
: base ( "*" )
{
if ( typeTable = = null )
{
throw PSTraceSource . NewArgumentNullException ( "typeTable" ) ;
}
2016-08-02 22:29:09 +02:00
TypeTable = typeTable ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Loads all entries from the typeData
/// </summary>
/// <param name="typeData"></param>
/// <param name="isRemove"></param>
public SessionStateTypeEntry ( TypeData typeData , bool isRemove )
: base ( "*" )
{
if ( typeData = = null )
{
throw PSTraceSource . NewArgumentNullException ( "typeData" ) ;
}
2016-08-02 22:29:09 +02:00
TypeData = typeData ;
IsRemove = isRemove ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
SessionStateTypeEntry entry ;
2016-08-02 22:29:09 +02:00
if ( FileName ! = null )
2016-03-30 23:20:52 +02:00
{
2016-08-02 22:29:09 +02:00
entry = new SessionStateTypeEntry ( FileName ) ;
2016-03-30 23:20:52 +02:00
}
2016-08-02 22:29:09 +02:00
else if ( TypeTable ! = null )
2016-03-30 23:20:52 +02:00
{
2016-08-02 22:29:09 +02:00
entry = new SessionStateTypeEntry ( TypeTable ) ;
2016-03-30 23:20:52 +02:00
}
else
{
2016-08-02 22:29:09 +02:00
entry = new SessionStateTypeEntry ( TypeData , IsRemove ) ;
2016-03-30 23:20:52 +02:00
}
entry . SetPSSnapIn ( this . PSSnapIn ) ;
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// The pathname of the types.ps1xml file. This can be null if
/// TypeTable constructor or TypeData constructor is used.
/// </summary>
2016-08-02 22:29:09 +02:00
public string FileName { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The TypeTable specified with constructor. This can be null if
/// FileName constructor or TypeData constructor is used.
/// </summary>
2016-08-02 22:29:09 +02:00
public TypeTable TypeTable { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The TypeData we want to update with. This can be null if
/// FileName constructor or TypeTable constructor is used.
/// </summary>
2016-08-02 22:29:09 +02:00
public TypeData TypeData { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The operation will be done on the typedata. This is only
/// meaningful when the TypeData constructor is used.
/// </summary>
2016-08-02 22:29:09 +02:00
public bool IsRemove { get ; }
2016-03-30 23:20:52 +02:00
//So that we can specify the type information on the fly,
//without using Types.ps1xml file
//public SessionStateTypeEntry(string name, xmlreader definition);
//public string Definition { get; }
}
/// <summary>
/// Format file configuration entry...
/// </summary>
public sealed class SessionStateFormatEntry : InitialSessionStateEntry
{
/// <summary>
/// Loads the entire formats file
/// </summary>
/// <param name="fileName"></param>
public SessionStateFormatEntry ( string fileName )
: base ( "*" )
{
if ( String . IsNullOrEmpty ( fileName ) | | fileName . Trim ( ) . Length = = 0 )
{
throw PSTraceSource . NewArgumentException ( "fileName" ) ;
}
2016-08-02 22:29:09 +02:00
FileName = fileName . Trim ( ) ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Loads all the format data specified in the formatTable
/// </summary>
/// <param name="formattable"></param>
public SessionStateFormatEntry ( FormatTable formattable )
: base ( "*" )
{
if ( formattable = = null )
{
throw PSTraceSource . NewArgumentNullException ( "formattable" ) ;
}
2016-08-02 22:29:09 +02:00
Formattable = formattable ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Loads all the format data specified in the typeDefinition
/// </summary>
/// <param name="typeDefinition"></param>
public SessionStateFormatEntry ( ExtendedTypeDefinition typeDefinition )
: base ( "*" )
{
if ( typeDefinition = = null )
{
throw PSTraceSource . NewArgumentNullException ( "typeDefinition" ) ;
}
2016-08-02 22:29:09 +02:00
FormatData = typeDefinition ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
SessionStateFormatEntry entry ;
2016-08-02 22:29:09 +02:00
if ( FileName ! = null )
2016-03-30 23:20:52 +02:00
{
2016-08-02 22:29:09 +02:00
entry = new SessionStateFormatEntry ( FileName ) ;
2016-03-30 23:20:52 +02:00
}
2016-08-02 22:29:09 +02:00
else if ( Formattable ! = null )
2016-03-30 23:20:52 +02:00
{
2016-08-02 22:29:09 +02:00
entry = new SessionStateFormatEntry ( Formattable ) ;
2016-03-30 23:20:52 +02:00
}
else
{
2016-08-02 22:29:09 +02:00
entry = new SessionStateFormatEntry ( FormatData ) ;
2016-03-30 23:20:52 +02:00
}
entry . SetPSSnapIn ( this . PSSnapIn ) ;
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// The name of the format file referenced by this entry...
/// </summary>
2016-08-02 22:29:09 +02:00
public string FileName { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The FormatTable specified with constructor. This can be null if
/// FileName constructor is used.
/// </summary>
2016-08-02 22:29:09 +02:00
public FormatTable Formattable { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The FormatData specified with constructor. This can be null if
/// FileName or FormatTable constructor is used
/// </summary>
2016-08-02 22:29:09 +02:00
public ExtendedTypeDefinition FormatData { get ; }
2016-03-30 23:20:52 +02:00
//So that we can specify the format information on the fly,
//without using Format.ps1xml file
//public SessionStateFormatEntry(string name, xmlreader definition);
//public string Definition { get; }
}
/// <summary>
/// An assembly to load for this sessionstate...
/// </summary>
public sealed class SessionStateAssemblyEntry : InitialSessionStateEntry
{
/// <summary>
/// Create a named entry for the assembly to load with both the
/// name and the path to the assembly as a backup.
/// </summary>
/// <param name="name">The name of the assembly to load</param>
/// <param name="fileName">The path to the assembly to use as an alternative</param>
public SessionStateAssemblyEntry ( string name , string fileName )
: base ( name )
{
2016-08-02 22:29:09 +02:00
FileName = fileName ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Create a named entry for the assembly to load, specifying
/// just the nanme
/// </summary>
/// <param name="name">The name of the assembly to load</param>
public SessionStateAssemblyEntry ( string name )
: base ( name )
{
;
}
/// <summary>
/// Shallow-clone this object
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateAssemblyEntry entry = new SessionStateAssemblyEntry ( Name , FileName ) ;
2016-03-30 23:20:52 +02:00
entry . SetPSSnapIn ( this . PSSnapIn ) ;
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// Return the assembly file name...
/// </summary>
2016-08-02 22:29:09 +02:00
public string FileName { get ; }
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// List a cmdlet to add to this session state entry
/// </summary>
public sealed class SessionStateCmdletEntry : SessionStateCommandEntry
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="implementingType"></param>
/// <param name="helpFileName"></param>
public SessionStateCmdletEntry ( string name , Type implementingType , string helpFileName )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
ImplementingType = implementingType ;
HelpFileName = helpFileName ;
CommandType = CommandTypes . Cmdlet ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="implementingType"></param>
/// <param name="helpFileName"></param>
/// <param name="visibility"></param>
internal SessionStateCmdletEntry ( string name , Type implementingType , string helpFileName , SessionStateEntryVisibility visibility )
: base ( name , visibility )
{
2016-08-02 22:29:09 +02:00
ImplementingType = implementingType ;
HelpFileName = helpFileName ;
CommandType = CommandTypes . Cmdlet ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns></returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateCmdletEntry entry = new SessionStateCmdletEntry ( Name , ImplementingType , HelpFileName , Visibility ) ;
2016-03-30 23:20:52 +02:00
entry . SetPSSnapIn ( this . PSSnapIn ) ;
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
///
/// </summary>
2016-08-02 22:29:09 +02:00
public Type ImplementingType { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
///
/// </summary>
2016-08-02 22:29:09 +02:00
public string HelpFileName { get ; }
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
public sealed class SessionStateProviderEntry : ConstrainedSessionStateEntry
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="implementingType"></param>
/// <param name="helpFileName"></param>
public SessionStateProviderEntry ( string name , Type implementingType , string helpFileName )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
ImplementingType = implementingType ;
HelpFileName = helpFileName ;
2016-03-30 23:20:52 +02:00
}
internal SessionStateProviderEntry ( string name , Type implementingType , string helpFileName , SessionStateEntryVisibility visibility )
: base ( name , visibility )
{
2016-08-02 22:29:09 +02:00
ImplementingType = implementingType ;
HelpFileName = helpFileName ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateProviderEntry entry = new SessionStateProviderEntry ( Name , ImplementingType , HelpFileName , this . Visibility ) ;
2016-03-30 23:20:52 +02:00
entry . SetPSSnapIn ( this . PSSnapIn ) ;
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
///
/// </summary>
2016-08-02 22:29:09 +02:00
public Type ImplementingType { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
///
/// </summary>
2016-08-02 22:29:09 +02:00
public string HelpFileName { get ; }
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
public sealed class SessionStateScriptEntry : SessionStateCommandEntry
{
/// <summary>
/// Create a session state command entry instance.
/// </summary>
/// <param name="path">The path to the script</param>
public SessionStateScriptEntry ( string path )
: base ( path , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Path = path ;
CommandType = CommandTypes . ExternalScript ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Create a session state command entry instance with the specified visiblity.
/// </summary>
/// <param name="path">The path to the script</param>
/// <param name="visibility">Visibility of the script.</param>
internal SessionStateScriptEntry ( string path , SessionStateEntryVisibility visibility )
: base ( path , visibility )
{
2016-08-02 22:29:09 +02:00
Path = path ;
CommandType = CommandTypes . ExternalScript ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateScriptEntry entry = new SessionStateScriptEntry ( Path , Visibility ) ;
2016-03-30 23:20:52 +02:00
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
///
/// </summary>
2016-08-02 22:29:09 +02:00
public string Path { get ; }
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
public sealed class SessionStateAliasEntry : SessionStateCommandEntry
{
/// <summary>
/// Define an alias entry to add to the initial session state
/// </summary>
/// <param name="name">Name of the aliase</param>
/// <param name="definition">The name of the command it resolves to</param>
public SessionStateAliasEntry ( string name , string definition )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Alias ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Define an alias entry to add to the initial session state
/// </summary>
/// <param name="name">Name of the aliase</param>
/// <param name="definition">The name of the command it resolves to</param>
/// <param name="description">A descripion of the purpose of the alias.</param>
public SessionStateAliasEntry ( string name , string definition , string description )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Alias ;
Description = description ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Define an alias entry to add to the initial session state
/// </summary>
/// <param name="name">Name of the aliase</param>
/// <param name="definition">The name of the command it resolves to</param>
/// <param name="description">A descripion of the purpose of the alias.</param>
/// <param name="options">Options defining the scope visiblity, readonly and constant</param>
public SessionStateAliasEntry ( string name , string definition , string description , ScopedItemOptions options )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Alias ;
Description = description ;
Options = options ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Define an alias entry to add to the initial session state
/// </summary>
/// <param name="name">Name of the aliase</param>
/// <param name="definition">The name of the command it resolves to</param>
/// <param name="description">A descripion of the purpose of the alias.</param>
/// <param name="options">Options defining the scope visiblity, readonly and constant</param>
/// <param name="visibility"></param>
internal SessionStateAliasEntry ( string name , string definition , string description ,
ScopedItemOptions options , SessionStateEntryVisibility visibility )
: base ( name , visibility )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Alias ;
Description = description ;
Options = options ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateAliasEntry entry = new SessionStateAliasEntry ( Name , Definition , Description , Options , Visibility ) ;
2016-03-30 23:20:52 +02:00
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// The string defining the body of this alias...
/// </summary>
2016-08-02 22:29:09 +02:00
public string Definition { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// A string describing this alias...
/// </summary>
2016-08-02 22:29:09 +02:00
public string Description { get ; } = String . Empty ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// Options controling scope visiblity and setability for this entry.
/// </summary>
2016-08-02 22:29:09 +02:00
public ScopedItemOptions Options { get ; } = ScopedItemOptions . None ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
public sealed class SessionStateApplicationEntry : SessionStateCommandEntry
{
/// <summary>
/// Used to define a permitted script in this session state. If the path is
/// "*", then any path is permitted.
/// </summary>
/// <param name="path">The full path to the application</param>
public SessionStateApplicationEntry ( string path )
: base ( path , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Path = path ;
CommandType = CommandTypes . Application ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Used to define a permitted script in this session state. If the path is
/// "*", then any path is permitted.
/// </summary>
/// <param name="path">The full path to the application</param>
/// <param name="visibility">Sets the external visibilty of the path.</param>
internal SessionStateApplicationEntry ( string path , SessionStateEntryVisibility visibility )
: base ( path , visibility )
{
2016-08-02 22:29:09 +02:00
Path = path ;
CommandType = CommandTypes . Application ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateApplicationEntry entry = new SessionStateApplicationEntry ( Path , Visibility ) ;
2016-03-30 23:20:52 +02:00
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// The path to this application...
/// </summary>
2016-08-02 22:29:09 +02:00
public string Path { get ; }
2016-03-30 23:20:52 +02:00
}
/// <summary>
///
/// </summary>
public sealed class SessionStateFunctionEntry : SessionStateCommandEntry
{
/// <summary>
/// Represents a function definition in an Initial session state object.
/// </summary>
/// <param name="name">The name of the function</param>
/// <param name="definition">The definition of the function</param>
/// <param name="options">Options controlling scope-related elements of this object</param>
/// <param name="helpFile">The name of the help file associated with the function</param>
public SessionStateFunctionEntry ( string name , string definition , ScopedItemOptions options , string helpFile )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Function ;
Options = options ;
ScriptBlock = ScriptBlock . Create ( Definition ) ;
ScriptBlock . LanguageMode = PSLanguageMode . FullLanguage ;
2016-03-30 23:20:52 +02:00
2016-08-02 22:29:09 +02:00
HelpFile = helpFile ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Represents a function definition in an Initial session state object.
/// </summary>
/// <param name="name">The name of the function</param>
/// <param name="definition">The definition of the function</param>
/// <param name="helpFile">The name of the help file associated with the function</param>
public SessionStateFunctionEntry ( string name , string definition , string helpFile )
: this ( name , definition , ScopedItemOptions . None , helpFile )
{
}
/// <summary>
/// Represents a function definition in an Initial session state object.
/// </summary>
/// <param name="name">The name of the function</param>
/// <param name="definition">The definition of the function</param>
public SessionStateFunctionEntry ( string name , string definition )
: this ( name , definition , ScopedItemOptions . None , null )
{
}
/// <summary>
/// This is an internal copy constructor.
/// </summary>
internal SessionStateFunctionEntry ( string name , string definition , ScopedItemOptions options ,
SessionStateEntryVisibility visibility , ScriptBlock scriptBlock , string helpFile )
: base ( name , visibility )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Function ;
Options = options ;
ScriptBlock = scriptBlock ;
HelpFile = helpFile ;
2016-03-30 23:20:52 +02:00
}
2016-06-22 04:17:13 +02:00
internal static SessionStateFunctionEntry GetDelayParsedFunctionEntry ( string name , string definition , bool isProductCode )
2016-03-30 23:20:52 +02:00
{
2016-06-22 04:17:13 +02:00
var sb = ScriptBlock . CreateDelayParsedScriptBlock ( definition , isProductCode ) ;
2016-03-30 23:20:52 +02:00
return new SessionStateFunctionEntry ( name , definition , ScopedItemOptions . None ,
SessionStateEntryVisibility . Public , sb , null ) ;
}
internal static SessionStateFunctionEntry GetDelayParsedFunctionEntry ( string name , string definition , ScriptBlock sb )
{
return new SessionStateFunctionEntry ( name , definition , ScopedItemOptions . None ,
SessionStateEntryVisibility . Public , sb , null ) ;
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateFunctionEntry entry = new SessionStateFunctionEntry ( Name , Definition , Options , Visibility , ScriptBlock , HelpFile ) ;
2016-03-30 23:20:52 +02:00
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// Sets the name of the help file associated with the function.
/// </summary>
internal void SetHelpFile ( string help )
{
2016-08-02 22:29:09 +02:00
HelpFile = help ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// The string to use to define this function...
/// </summary>
2016-08-02 22:29:09 +02:00
public string Definition { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The script block for this function.
/// </summary>
2016-08-02 22:29:09 +02:00
internal ScriptBlock ScriptBlock { get ; set ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// Options controling scope visiblity and setability for this entry.
/// </summary>
2016-08-02 22:29:09 +02:00
public ScopedItemOptions Options { get ; } = ScopedItemOptions . None ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// The name of the help file associated with the function.
/// </summary>
2016-08-02 22:29:09 +02:00
public string HelpFile { get ; private set ; }
2016-03-30 23:20:52 +02:00
}
#if ! CORECLR // Workflow Not Supported On CSS
/// <summary>
///
/// </summary>
public sealed class SessionStateWorkflowEntry : SessionStateCommandEntry
{
/// <summary>
/// Represents a workflow definition in an Initial session state object.
/// </summary>
/// <param name="name">The name of the workflow</param>
/// <param name="definition">The definition of the workflow</param>
/// <param name="options">Options controlling scope-related elements of this object</param>
/// <param name="helpFile">The name of the help file associated with the workflow</param>
public SessionStateWorkflowEntry ( string name , string definition , ScopedItemOptions options , string helpFile )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
CommandType = CommandTypes . Workflow ;
Options = options ;
HelpFile = helpFile ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Represents a workflow definition in an Initial session state object.
/// </summary>
/// <param name="name">The name of the workflow</param>
/// <param name="definition">The definition of the workflow</param>
/// <param name="helpFile">The name of the help file associated with the workflow</param>
public SessionStateWorkflowEntry ( string name , string definition , string helpFile )
: this ( name , definition , ScopedItemOptions . None , helpFile )
{
}
/// <summary>
/// Represents a workflow definition in an Initial session state object.
/// </summary>
/// <param name="name">The name of the workflow</param>
/// <param name="definition">The definition of the workflow</param>
public SessionStateWorkflowEntry ( string name , string definition )
: this ( name , definition , ScopedItemOptions . None , null )
{
}
/// <summary>
/// This is an internal copy constructor.
/// </summary>
internal SessionStateWorkflowEntry ( string name , string definition , ScopedItemOptions options , SessionStateEntryVisibility visibility , WorkflowInfo workflow , string helpFile )
: base ( name , visibility )
{
2016-08-02 22:29:09 +02:00
Definition = definition ;
Options = options ;
WorkflowInfo = workflow ;
HelpFile = helpFile ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
2016-08-02 22:29:09 +02:00
SessionStateWorkflowEntry entry = new SessionStateWorkflowEntry ( Name , Definition , Options , Visibility , WorkflowInfo , HelpFile ) ;
2016-03-30 23:20:52 +02:00
entry . SetModule ( this . Module ) ;
return entry ;
}
/// <summary>
/// Sets the name of the help file associated with the function.
/// </summary>
internal void SetHelpFile ( string help )
{
2016-08-02 22:29:09 +02:00
HelpFile = help ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// The string to use to define this function...
/// </summary>
2016-08-02 22:29:09 +02:00
public string Definition { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The script block for this function.
/// </summary>
2016-08-02 22:29:09 +02:00
internal WorkflowInfo WorkflowInfo { get ; set ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// Options controling scope visiblity and setability for this entry.
/// </summary>
2016-08-02 22:29:09 +02:00
public ScopedItemOptions Options { get ; } = ScopedItemOptions . None ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// The name of the help file associated with the function.
/// </summary>
2016-08-02 22:29:09 +02:00
public string HelpFile { get ; private set ; }
2016-03-30 23:20:52 +02:00
}
#endif
/// <summary>
///
/// </summary>
public sealed class SessionStateVariableEntry : ConstrainedSessionStateEntry
{
/// <summary>
/// Is used to define a variable that should be created when
/// the runspace is opened. Note - if this object is cloned,
/// then the clone will contain a reference to the original object
/// not a clone of it.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="value">The value to set the variable to</param>
/// <param name="description">A descriptive string to attach to the variable.</param>
public SessionStateVariableEntry ( string name , object value , string description )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Value = value ;
Description = description ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Is used to define a variable that should be created when
/// the runspace is opened. Note - if this object is cloned,
/// then the clone will contain a reference to the original object
/// not a clone of it.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="value">The value to set the variable to</param>
/// <param name="description">A descriptive string to attach to the variable.</param>
/// <param name="options">Options like readonly, constant, allscope, etc.</param>
public SessionStateVariableEntry ( string name , object value , string description , ScopedItemOptions options )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Value = value ;
Description = description ;
Options = options ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Is used to define a variable that should be created when
/// the runspace is opened. Note - if this object is cloned,
/// then the clone will contain a reference to the original object
/// not a clone of it.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="value">The value to set the variable to</param>
/// <param name="description">A descriptive string to attach to the variable.</param>
/// <param name="options">Options like readonly, constant, allscope, etc.</param>
/// <param name="attributes">A list of attributes to attach to the variable.</param>
public SessionStateVariableEntry ( string name , object value , string description ,
ScopedItemOptions options , Collection < Attribute > attributes )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Value = value ;
Description = description ;
Options = options ;
2016-03-30 23:20:52 +02:00
_attributes = attributes ;
}
/// <summary>
/// Is used to define a variable that should be created when
/// the runspace is opened. Note - if this object is cloned,
/// then the clone will contain a reference to the original object
/// not a clone of it.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="value">The value to set the variable to</param>
/// <param name="description">A descriptive string to attach to the variable.</param>
/// <param name="options">Options like readonly, constant, allscope, etc.</param>
/// <param name="attribute">A single attribute to attach to the variable.</param>
public SessionStateVariableEntry ( string name , object value , string description ,
ScopedItemOptions options , Attribute attribute )
: base ( name , SessionStateEntryVisibility . Public )
{
2016-08-02 22:29:09 +02:00
Value = value ;
Description = description ;
Options = options ;
2016-03-30 23:20:52 +02:00
_attributes = new Collection < Attribute > ( ) ;
_attributes . Add ( attribute ) ;
}
/// <summary>
/// Is used to define a variable that should be created when
/// the runspace is opened. Note - if this object is cloned,
/// then the clone will contain a reference to the original object
/// not a clone of it.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="value">The value to set the variable to</param>
/// <param name="description">A descriptive string to attach to the variable.</param>
/// <param name="options">Options like readonly, constant, allscope, etc.</param>
/// <param name="attributes">A single attribute to attach to the variable.</param>
/// <param name="visibility"></param>
internal SessionStateVariableEntry ( string name , object value , string description ,
ScopedItemOptions options , Collection < Attribute > attributes , SessionStateEntryVisibility visibility )
: base ( name , visibility )
{
2016-08-02 22:29:09 +02:00
Value = value ;
Description = description ;
Options = options ;
2016-03-30 23:20:52 +02:00
_attributes = attributes ;
}
/// <summary>
/// Shallow-clone this object...
/// </summary>
/// <returns>The cloned object</returns>
public override InitialSessionStateEntry Clone ( )
{
// Copy the attribute collection if necessary...
Collection < Attribute > attrs = null ;
if ( _attributes ! = null & & _attributes . Count > 0 )
attrs = new Collection < Attribute > ( _attributes ) ;
2016-08-02 22:29:09 +02:00
return new SessionStateVariableEntry ( Name , Value , Description , Options , attrs , Visibility ) ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// The value to bind to this variable.
/// </summary>
2016-08-02 22:29:09 +02:00
public object Value { get ; }
2016-03-30 23:20:52 +02:00
/// <summary>
/// The description associated with this variable.
/// </summary>
2016-08-02 22:29:09 +02:00
public string Description { get ; } = String . Empty ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// The options associated with this variable (e.g. readonly, allscope, etc.)
/// </summary>
2016-08-02 22:29:09 +02:00
public ScopedItemOptions Options { get ; } = ScopedItemOptions . None ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// The attributes that will be attached to this object.
/// </summary>
public Collection < Attribute > Attributes
{
get
{
if ( _attributes = = null )
_attributes = new Collection < Attribute > ( ) ;
return _attributes ;
}
}
private Collection < Attribute > _attributes ;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class InitialSessionStateEntryCollection < T > : IEnumerable < T > where T : InitialSessionStateEntry
{
/// <summary>
/// Create an empty collection...
/// </summary>
public InitialSessionStateEntryCollection ( )
{
_internalCollection = new Collection < T > ( ) ;
}
/// <summary>
/// Create an new collection, copying in the passed items...
/// </summary>
/// <param name="items"></param>
public InitialSessionStateEntryCollection ( IEnumerable < T > items )
{
if ( items = = null )
{
throw new ArgumentNullException ( "items" ) ;
}
_internalCollection = new Collection < T > ( ) ;
foreach ( T item in items )
{
_internalCollection . Add ( item ) ;
}
}
/// <summary>
/// Clone this collection
/// </summary>
/// <returns>The cloned object</returns>
public InitialSessionStateEntryCollection < T > Clone ( )
{
InitialSessionStateEntryCollection < T > result ;
lock ( _syncObject )
{
result = new InitialSessionStateEntryCollection < T > ( ) ;
foreach ( T item in _internalCollection )
{
result . Add ( ( T ) item . Clone ( ) ) ;
}
}
return result ;
}
/// <summary>
/// Reset the collection
/// </summary>
public void Reset ( )
{
lock ( _syncObject )
{
_internalCollection . Clear ( ) ;
}
}
/// <summary>
/// Returns a count of the number of items in the collection...
/// </summary>
public int Count
{
get { return _internalCollection . Count ; }
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this [ int index ]
{
get
{
T result ;
lock ( _syncObject )
{
result = _internalCollection [ index ] ;
}
return result ;
}
}
//To find the entries based on name.
//Why collection - Different SnapIn/modules and same entity names.
//If used on command collection entry, then for the same name, one can have multiple output
/// <summary>
/// To find the entries based on name.
/// Why collection - Different SnapIn/modules and same entity names.
/// If used on command collection entry, then for the same name, one can have multiple output
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public Collection < T > this [ string name ]
{
get
{
Collection < T > result = new Collection < T > ( ) ;
lock ( _syncObject )
{
foreach ( T element in _internalCollection )
{
if ( element . Name . Equals ( name , StringComparison . OrdinalIgnoreCase ) )
{
result . Add ( element ) ;
}
}
}
return result ;
}
}
/// <summary>
/// Find entries based on string name which can include wildcards.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
internal Collection < T > LookUpByName ( string name )
{
if ( name = = null ) { throw new PSArgumentNullException ( "name" ) ; }
Collection < T > result = new Collection < T > ( ) ;
WildcardPattern namePattern = WildcardPattern . Get ( name , WildcardOptions . IgnoreCase ) ;
lock ( _syncObject )
{
foreach ( T element in _internalCollection )
{
if ( namePattern . IsMatch ( element . Name ) )
{
result . Add ( element ) ;
}
}
}
return result ;
}
/// <summary>
///
/// </summary>
/// <param name="index"></param>
public void RemoveItem ( int index )
{
lock ( _syncObject )
{
_internalCollection . RemoveAt ( index ) ;
}
}
/// <summary>
/// Remove a number of items starting at the specified index.
/// </summary>
/// <param name="index"></param>
/// <param name="count"></param>
public void RemoveItem ( int index , int count )
{
lock ( _syncObject )
{
while ( count - - > 0 )
{
_internalCollection . RemoveAt ( index ) ;
}
}
}
/// <summary>
/// Clears the collection...
/// </summary>
public void Clear ( )
{
lock ( _syncObject )
{
_internalCollection . Clear ( ) ;
}
}
/// <summary>
/// This overload exists so that we can remove items based on the item name, rather than
/// its position in the collection. The type argument can be null but we'll throw an error if
/// we can't distinguish between multiple entries of the same name but different types
/// and the type hasn't been specified.
/// BUGBUG - brucepay - the throw thing is not implemented yet...
/// </summary>
/// <param name="name">The name of the element to remove</param>
/// <param name="type">The type of object to remove, can be null to remove any type.</param>
public void Remove ( string name , object type )
{
if ( name = = null )
throw new ArgumentNullException ( "name" ) ;
lock ( _syncObject )
{
Type objType = null ;
if ( type ! = null )
{
objType = type as Type ;
if ( objType = = null )
objType = type . GetType ( ) ;
}
// Work backwards through the collection...
for ( int i = _internalCollection . Count - 1 ; i > = 0 ; i - - )
{
T element = _internalCollection [ i ] ;
if ( element = = null )
continue ;
if ( ( objType = = null | | element . GetType ( ) = = objType ) & &
String . Equals ( element . Name , name , StringComparison . OrdinalIgnoreCase ) )
{
_internalCollection . RemoveAt ( i ) ;
}
}
}
}
/// <summary>
/// Add an item to this collection.
/// </summary>
/// <param name="item">The item to add...</param>
public void Add ( T item )
{
if ( item = = null )
throw new ArgumentNullException ( "item" ) ;
lock ( _syncObject )
{
_internalCollection . Add ( item ) ;
}
}
/// <summary>
///
/// </summary>
/// <param name="items"></param>
public void Add ( IEnumerable < T > items )
{
if ( items = = null )
throw new ArgumentNullException ( "items" ) ;
lock ( _syncObject )
{
foreach ( T element in items )
{
_internalCollection . Add ( element ) ;
}
}
}
/// <summary>
/// Get enumerator for this collection.
/// </summary>
/// <returns></returns>
/// <!--
/// Enumerator work is not thread safe by default. Any code trying
/// to do enumeration on this collection should lock it first.
///
/// Need to document this.
/// -->
IEnumerator System . Collections . IEnumerable . GetEnumerator ( )
{
return _internalCollection . GetEnumerator ( ) ;
}
/// <summary>
/// Get enumerator for this collection.
/// </summary>
/// <returns></returns>
/// <!--
/// Enumerator work is not thread safe by default. Any code trying
/// to do enumeration on this collection should lock it first.
///
/// Need to document this.
/// -->
IEnumerator < T > System . Collections . Generic . IEnumerable < T > . GetEnumerator ( )
{
return _internalCollection . GetEnumerator ( ) ;
}
private Collection < T > _internalCollection ;
//object to use for locking
2016-07-29 22:02:49 +02:00
private object _syncObject = new object ( ) ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Allows you to define the set of elements that should be
/// present when Session State is created.
/// </summary>
public class InitialSessionState
{
#region Helper methods for restricting commands needed by implicit and interactive remoting
2016-08-03 04:00:50 +02:00
private static void RemoveDisallowedEntries < T > ( InitialSessionStateEntryCollection < T > list , List < string > allowedNames , Func < T , string > nameGetter )
2016-03-30 23:20:52 +02:00
where T : InitialSessionStateEntry
{
List < string > namesToRemove = new List < string > ( ) ;
foreach ( T entry in list )
{
string entryName = nameGetter ( entry ) ;
// if entryName is not present in allowedNames list, then remove it
if ( ! allowedNames . Exists ( allowedName = > allowedName . Equals ( entryName , StringComparison . OrdinalIgnoreCase ) ) )
{
namesToRemove . Add ( entry . Name ) ;
}
}
foreach ( string nameToRemove in namesToRemove )
{
list . Remove ( nameToRemove , null /* remove any type with this name */ ) ;
}
}
2016-08-03 04:00:50 +02:00
private static void MakeDisallowedEntriesPrivate < T > ( InitialSessionStateEntryCollection < T > list , List < string > allowedNames , Func < T , string > nameGetter )
2016-03-30 23:20:52 +02:00
where T : ConstrainedSessionStateEntry
{
foreach ( T entry in list )
{
string entryName = nameGetter ( entry ) ;
// Aliases to allowed commands are OK
SessionStateAliasEntry aliasEntry = entry as SessionStateAliasEntry ;
2016-07-29 22:02:49 +02:00
if ( aliasEntry ! = null )
2016-03-30 23:20:52 +02:00
{
2016-07-29 22:02:49 +02:00
if ( allowedNames . Exists ( allowedName = > allowedName . Equals ( aliasEntry . Definition , StringComparison . OrdinalIgnoreCase ) ) )
2016-03-30 23:20:52 +02:00
{
aliasEntry . Visibility = SessionStateEntryVisibility . Public ;
continue ;
}
}
// if entryName is not present in allowedNames list, then remove it
if ( ! allowedNames . Exists ( allowedName = > allowedName . Equals ( entryName , StringComparison . OrdinalIgnoreCase ) ) )
{
entry . Visibility = SessionStateEntryVisibility . Private ;
}
}
}
/// <summary>
/// Creates an initial session state from a PSSC configuration file
/// </summary>
/// <param name="path">The path to the PSSC session configuration file</param>
/// <returns></returns>
public static InitialSessionState CreateFromSessionConfigurationFile ( string path )
{
return CreateFromSessionConfigurationFile ( path , null ) ;
}
/// <summary>
/// Creates an initial session state from a PSSC configuration file
/// </summary>
/// <param name="path">The path to the PSSC session configuration file</param>
/// <param name="roleVerifier">
/// The verifier that PowerShell should call to determine if groups in the Role entry apply to the
/// target session. If you have a WindowsPrincipal for a user, for example, create a Function that
/// checks windowsPrincipal.IsInRole().
/// </param>
/// <returns></returns>
public static InitialSessionState CreateFromSessionConfigurationFile ( string path , Func < string , bool > roleVerifier )
{
Remoting . DISCPowerShellConfiguration discConfiguration = new Remoting . DISCPowerShellConfiguration ( path , roleVerifier ) ;
return discConfiguration . GetInitialSessionState ( null ) ;
}
/// <summary>
/// Creates an <see cref="InitialSessionState"/> instance that exposes only the minimal
/// set of commands needed by give set of <paramref name="sessionCapabilities"/>
/// All commands that are not needed are made private in order to minimize the attack surface.
/// </summary>
/// <param name="sessionCapabilities">
/// What capabilities the session should have.
/// </param>
/// <returns></returns>
2016-08-03 04:00:50 +02:00
public static InitialSessionState CreateRestricted ( SessionCapabilities sessionCapabilities )
2016-03-30 23:20:52 +02:00
{
// only remote server has been requested
if ( SessionCapabilities . RemoteServer = = sessionCapabilities )
{
return CreateRestrictedForRemoteServer ( ) ;
}
#if CORECLR // Workflow Not Supported On CSS
if ( ( sessionCapabilities & SessionCapabilities . WorkflowServer ) = = SessionCapabilities . WorkflowServer )
{
throw PSTraceSource . NewNotSupportedException ( ParserStrings . WorkflowNotSupportedInPowerShellCore ) ;
}
#else
// only workflow has been requested
if ( SessionCapabilities . WorkflowServer = = sessionCapabilities )
{
return CreateRestrictedForWorkflowServerMinimum ( ) ;
}
// workflow server with remoting support has been requested
if ( sessionCapabilities = = ( SessionCapabilities . WorkflowServer | SessionCapabilities . RemoteServer ) )
{
return CreateRestrictedForWorkflowServer ( ) ;
}
if ( sessionCapabilities = = ( SessionCapabilities . WorkflowServer | SessionCapabilities . RemoteServer | SessionCapabilities . Language ) )
{
return CreateRestrictedForWorkflowServerWithFullLanguage ( ) ;
}
#endif
return Create ( ) ;
}
2016-08-03 04:00:50 +02:00
private static InitialSessionState CreateRestrictedForRemoteServer ( )
2016-03-30 23:20:52 +02:00
{
InitialSessionState iss = Create ( ) ;
iss . LanguageMode = PSLanguageMode . NoLanguage ;
iss . ThrowOnRunspaceOpenError = true ;
iss . UseFullLanguageModeInDebugger = false ;
iss . Commands . Add ( BuiltInFunctions ) ;
iss . Commands . Add ( BuiltInAliases ) ;
// Load the default snapins - all commands will be private by default.
Collection < PSSnapInInfo > defaultSnapins = PSSnapInReader . ReadEnginePSSnapIns ( ) ;
foreach ( PSSnapInInfo si in defaultSnapins )
{
// ImportPSSnapIn always sets "out warning" to "null"; all our internal calls ignore/discard "out warning"
PSSnapInException warning ;
iss . ImportPSSnapIn ( si , out warning ) ;
}
//
// restrict what gets exposed
//
List < string > allowedCommands = new List < string > ( ) ;
// required by implicit remoting and interactive remoting
allowedCommands . Add ( "Get-Command" ) ;
allowedCommands . Add ( "Get-FormatData" ) ;
allowedCommands . Add ( "Clear-Host" ) ;
allowedCommands . Add ( "Select-Object" ) ; // used to serialize exactly the properties that we need (+ at the right depth)
// used if available by implicit remoting
allowedCommands . Add ( "Get-Help" ) ; // used when displaying help for implicit remoting proxy functions
allowedCommands . Add ( "Measure-Object" ) ; // used to have nice progress bars when import/export-pssession is running
// required by interactive remoting
allowedCommands . Add ( "Out-Default" ) ; // appended to every command line
allowedCommands . Add ( "Exit-PSSession" ) ; // used by the user to exit the sesion
// We don't remove these entries so that they can be called by commands in the runspace.
// Setting them to 'Private' ensures that the user can't call them.
MakeDisallowedEntriesPrivate (
iss . Commands ,
allowedCommands ,
commandEntry = > commandEntry . Name ) ;
// Ensure that only PowerShell core formats are included in the restricted session.
IncludePowerShellCoreFormats ( iss ) ;
List < string > allowedTypes = new List < string > ( ) ;
allowedTypes . Add ( "types.ps1xml" ) ;
allowedTypes . Add ( "typesV3.ps1xml" ) ;
RemoveDisallowedEntries (
iss . Types ,
allowedTypes ,
typeEntry = > IO . Path . GetFileName ( typeEntry . FileName ) ) ;
// No providers are visible by default
2016-07-29 22:02:49 +02:00
foreach ( SessionStateProviderEntry provider in iss . Providers )
2016-03-30 23:20:52 +02:00
{
provider . Visibility = SessionStateEntryVisibility . Private ;
}
// Add built-in variables.
iss . Variables . Add ( BuiltInVariables ) ;
//
// wrap some commands in a proxy function to restrict their parameters
//
foreach ( KeyValuePair < string , CommandMetadata > proxyFunction in CommandMetadata . GetRestrictedCommands ( SessionCapabilities . RemoteServer ) )
{
string commandName = proxyFunction . Key ;
// make the cmdlet private
Collection < SessionStateCommandEntry > originalCmdlet = iss . Commands [ commandName ] ;
Diagnostics . Assert ( originalCmdlet ! = null , "Proxied cmdlets should be imported at this point" ) ;
Diagnostics . Assert ( originalCmdlet . Count = = 1 , "Exactly one cmdlet with a given name" ) ;
originalCmdlet [ 0 ] . Visibility = SessionStateEntryVisibility . Private ;
// and add a public proxy function
string proxyBody = ProxyCommand . Create ( proxyFunction . Value , "" , false ) ;
iss . Commands . Add ( new SessionStateFunctionEntry ( commandName , proxyBody ) ) ;
}
return iss ;
}
2016-04-06 21:01:07 +02:00
// Porting note: moved to Platform so we have one list to maintain
2016-07-29 22:02:49 +02:00
private static string [ ] s_PSCoreFormatFileNames = Platform . FormatFileNames . ToArray ( ) ;
2016-04-06 21:01:07 +02:00
2016-03-30 23:20:52 +02:00
private static void IncludePowerShellCoreFormats ( InitialSessionState iss )
{
string psHome = Utils . GetApplicationBase ( Utils . DefaultPowerShellShellID ) ;
if ( string . IsNullOrEmpty ( psHome ) )
{
return ;
}
iss . Formats . Clear ( ) ;
2016-07-29 22:02:49 +02:00
foreach ( var coreFormat in s_PSCoreFormatFileNames )
2016-03-30 23:20:52 +02:00
{
iss . Formats . Add ( new SessionStateFormatEntry ( Path . Combine ( psHome , coreFormat ) ) ) ;
}
}
#if ! CORECLR // Workflow Not Supported On CSS
private static List < string > allowedAliases = new List < string >
{
"compare" ,
"diff" ,
"%" ,
"foreach" ,
"exsn" ,
"fc" ,
"fl" ,
"ft" ,
"fw" ,
"gcm" ,
"gjb" ,
"gmo" ,
"gv" ,
"group" ,
"ipmo" ,
"measure" ,
"rv" ,
"rcjb" ,
"rjb" ,
"rmo" ,
"rujb" ,
"select" ,
"set" ,
"sv" ,
"sort" ,
"spjb" ,
"sujb" ,
"wjb" ,
"?" ,
"where"
} ;
2016-08-03 04:00:50 +02:00
private static InitialSessionState CreateRestrictedForWorkflowServer ( )
2016-03-30 23:20:52 +02:00
{
InitialSessionState iss = CreateDefault ( ) ;
iss . LanguageMode = PSLanguageMode . NoLanguage ;
iss . ThrowOnRunspaceOpenError = true ;
iss . UseFullLanguageModeInDebugger = false ;
// WIN8:551312 M3P endpoint should have NO application exposed
//
foreach ( SessionStateCommandEntry entry in iss . Commands )
{
if ( entry . GetType ( ) = = typeof ( SessionStateApplicationEntry ) )
{
iss . Commands . Remove ( entry . Name , entry ) ;
break ;
}
}
//
// restrict what gets exposed
//
2016-07-29 22:02:49 +02:00
List < string > allowedCommands = new List < string > ( ) ;
2016-03-30 23:20:52 +02:00
allowedCommands . AddRange ( JobCmdlets ) ;
allowedCommands . AddRange ( ImplicitRemotingCmdlets ) ;
allowedCommands . AddRange ( MiscCmdlets ) ;
allowedCommands . AddRange ( AutoDiscoveryCmdlets ) ;
// make all other commands private
MakeDisallowedEntriesPrivate (
iss . Commands ,
allowedCommands ,
commandEntry = > commandEntry . Name ) ;
foreach ( SessionStateCommandEntry entry in iss . Commands )
{
if ( entry . GetType ( ) = = typeof ( SessionStateAliasEntry ) )
{
2016-07-29 22:02:49 +02:00
if ( allowedAliases . Contains ( entry . Name , StringComparer . OrdinalIgnoreCase ) )
2016-03-30 23:20:52 +02:00
{
entry . Visibility = SessionStateEntryVisibility . Public ;
}
else
{
entry . Visibility = SessionStateEntryVisibility . Private ;
}
}
}
2016-04-06 21:01:07 +02:00
// Porting note: copy so it can be modified
List < string > allowedFormats = new List < string > ( Platform . FormatFileNames ) ;
2016-03-30 23:20:52 +02:00
RemoveDisallowedEntries (
iss . Formats ,
allowedFormats ,
formatEntry = > IO . Path . GetFileName ( formatEntry . FileName ) ) ;
2016-04-06 21:01:07 +02:00
// Porting note: type files were deprecated
2016-03-30 23:20:52 +02:00
List < string > allowedTypes = new List < string > ( ) ;
allowedTypes . AddRange ( DefaultTypeFiles ) ;
RemoveDisallowedEntries (
iss . Types ,
allowedTypes ,
typeEntry = > IO . Path . GetFileName ( typeEntry . FileName ) ) ;
iss . Variables . Clear ( ) ; // no variables are needed for workflow server - remove all of them
return iss ;
}
2016-08-03 04:00:50 +02:00
private static InitialSessionState CreateRestrictedForWorkflowServerWithFullLanguage ( )
2016-03-30 23:20:52 +02:00
{
InitialSessionState iss = CreateDefault ( ) ;
iss . LanguageMode = PSLanguageMode . FullLanguage ;
iss . ThrowOnRunspaceOpenError = true ;
iss . UseFullLanguageModeInDebugger = false ;
// WIN8:551312 M3P endpoint should have NO application exposed
//
foreach ( SessionStateCommandEntry entry in iss . Commands )
{
if ( entry . GetType ( ) = = typeof ( SessionStateApplicationEntry ) )
{
iss . Commands . Remove ( entry . Name , entry ) ;
break ;
}
}
//
// restrict what gets exposed
//
List < string > allowedCommands = new List < string > ( ) ;
allowedCommands . AddRange ( JobCmdlets ) ;
allowedCommands . AddRange ( ImplicitRemotingCmdlets ) ;
allowedCommands . AddRange ( MiscCmdlets ) ;
allowedCommands . AddRange ( MiscCommands ) ;
allowedCommands . AddRange ( AutoDiscoveryCmdlets ) ;
allowedCommands . AddRange ( LanguageHelperCmdlets ) ;
// Exposing Debug cmdlets in only Full language WF server
// because for debugging one needs full language capabilities
2016-07-29 22:02:49 +02:00
allowedCommands . AddRange ( DebugCmdlets ) ;
2016-03-30 23:20:52 +02:00
// make all other commands private
MakeDisallowedEntriesPrivate (
iss . Commands ,
allowedCommands ,
commandEntry = > commandEntry . Name ) ;
foreach ( SessionStateCommandEntry entry in iss . Commands )
{
if ( entry . GetType ( ) = = typeof ( SessionStateAliasEntry ) )
{
if ( allowedAliases . Contains ( entry . Name , StringComparer . OrdinalIgnoreCase ) )
{
entry . Visibility = SessionStateEntryVisibility . Public ;
}
else
{
entry . Visibility = SessionStateEntryVisibility . Private ;
}
}
}
2016-04-06 21:01:07 +02:00
// Porting note: copy so it can be modified
List < string > allowedFormats = new List < string > ( Platform . FormatFileNames ) ;
2016-03-30 23:20:52 +02:00
RemoveDisallowedEntries (
iss . Formats ,
allowedFormats ,
formatEntry = > IO . Path . GetFileName ( formatEntry . FileName ) ) ;
2016-04-06 21:01:07 +02:00
// Porting note: type files were deprecated
2016-03-30 23:20:52 +02:00
List < string > allowedTypes = new List < string > ( ) ;
allowedTypes . AddRange ( DefaultTypeFiles ) ;
RemoveDisallowedEntries (
iss . Types ,
allowedTypes ,
typeEntry = > IO . Path . GetFileName ( typeEntry . FileName ) ) ;
iss . Variables . Clear ( ) ; // no variables are needed for workflow server - remove all of them
// set a preference variable to indicate Get-Command should show
// return only loaded public commands
2016-07-29 22:02:49 +02:00
Hashtable parameters = new Hashtable { { "Get-Command:ListImported" , true } } ;
2016-03-30 23:20:52 +02:00
iss . Variables . Add ( new SessionStateVariableEntry ( "PSDefaultParameterValues" , parameters , "Default Get-Command Action" ) ) ;
return iss ;
}
2016-08-03 04:00:50 +02:00
private static InitialSessionState CreateRestrictedForWorkflowServerMinimum ( )
2016-03-30 23:20:52 +02:00
{
InitialSessionState iss = CreateDefault ( ) ;
iss . LanguageMode = PSLanguageMode . NoLanguage ;
iss . ThrowOnRunspaceOpenError = true ;
iss . UseFullLanguageModeInDebugger = false ;
// WIN8:551312 M3P endpoint should have NO application exposed
//
foreach ( SessionStateCommandEntry entry in iss . Commands )
{
if ( entry . GetType ( ) = = typeof ( SessionStateApplicationEntry ) )
{
iss . Commands . Remove ( entry . Name , entry ) ;
break ;
}
}
//
// restrict what gets exposed
//
// required by implicit remoting and interactive remoting
List < string > allowedCommands = new List < string >
{
"Get-Command"
} ;
allowedCommands . AddRange ( JobCmdlets ) ;
allowedCommands . AddRange ( MiscCmdlets ) ;
// make all other commands private
MakeDisallowedEntriesPrivate (
iss . Commands ,
allowedCommands ,
commandEntry = > commandEntry . Name ) ;
iss . Formats . Clear ( ) ;
List < string > allowedTypes = new List < string > ( ) ;
allowedTypes . AddRange ( DefaultTypeFiles ) ;
RemoveDisallowedEntries (
iss . Types ,
allowedTypes ,
typeEntry = > IO . Path . GetFileName ( typeEntry . FileName ) ) ;
iss . Variables . Clear ( ) ; // no variables are needed for workflow server - remove all of them
// Disable module autodiscovery
SessionStateVariableEntry ssve = new SessionStateVariableEntry ( "PSDisableModuleAutoDiscovery" ,
true , "True if we disable module autodiscovery" , ScopedItemOptions . Constant ) ;
iss . Variables . Add ( ssve ) ;
return iss ;
}
private static readonly string [ ] JobCmdlets = {
"Get-Job" , "Stop-Job" , "Wait-Job" , "Suspend-Job" , "Resume-Job" ,
"Remove-Job" , "Receive-Job"
} ;
private static readonly string [ ] ImplicitRemotingCmdlets = {
"Get-Command" , "Select-Object" , "Measure-Object" ,
"Get-Help" , "Get-FormatData" , "Exit-PSSession" ,
"Out-Default"
} ;
private static readonly string [ ] AutoDiscoveryCmdlets = { "Get-Module" } ;
private static readonly string [ ] LanguageHelperCmdlets = {
"Compare-Object" ,
"ForEach-Object" ,
"Group-Object" ,
"Sort-Object" ,
"Where-Object" ,
"Out-File" ,
"Out-Null" ,
"Out-String" ,
"Format-Custom" ,
"Format-List" ,
"Format-Table" ,
"Format-Wide" ,
"Remove-Module" ,
"Get-Variable" ,
"Set-Variable" ,
"Remove-Variable" ,
"Get-Credential" ,
"Set-StrictMode"
} ;
/// <summary>
/// Following cmdlets are needed for debugging support starting WinBlue
/// </summary>
private static readonly string [ ] DebugCmdlets = {
"Disable-PSBreakpoint" ,
"Enable-PSBreakpoint" ,
"Get-PSBreakpoint" ,
"Remove-PSBreakpoint" ,
"Set-PSBreakpoint"
} ;
/// <summary>
/// this cmdlets are exposed due to some bugs. Need to figure out if
/// they are still required
/// </summary>
2016-07-29 22:02:49 +02:00
private static readonly string [ ] MiscCmdlets = { "Join-Path" , "Import-Module" } ;
2016-03-30 23:20:52 +02:00
private static readonly string [ ] MiscCommands = { "TabExpansion2" } ;
2016-07-29 22:02:49 +02:00
private static readonly string [ ] DefaultTypeFiles = { "types.ps1xml" , "typesv3.ps1xml" } ;
2016-03-30 23:20:52 +02:00
#endif
#endregion
/// <summary>
/// ctor for Custom-Shell - Do we need this?
/// </summary>
protected InitialSessionState ( )
{
}
// Creates an empty EE
/// <summary>
/// Creates an empty InitialSessionState object...
/// </summary>
/// <returns></returns>
public static InitialSessionState Create ( )
{
InitialSessionState iss = new InitialSessionState ( ) ;
//TODO: the following code is probably needed for the hosted constrained runspace
// There are too many things that depend on the built-in variables. At the same time,
// these variables can't be public or they become a security issue.
// This change still needs to be spec-reviewed before turning it on. It also seems to
// be causing test failures - i suspect due to lack test isolation - brucepay Mar 06/2008
#if false
// Add the default variables and make them private...
iss . Variables . Add ( BuiltInVariables ) ;
foreach ( SessionStateVariableEntry v in iss . Variables )
{
v . Visibility = SessionStateEntryVisibility . Private ;
}
#endif
return iss ;
}
/// <summary>
/// Creates the default PowerShell one with default cmdlets, provider etc.
/// BuiltIn functions, aliases need to be available through default
/// InitialSessionstate constructor. Need to have this discussion for packaging as well.
/// </summary>
/// <returns></returns>
public static InitialSessionState CreateDefault ( )
{
// Read all of the registered PSSnapins
Collection < PSSnapInInfo > defaultSnapins ;
PSSnapInException warning ;
InitialSessionState ss = new InitialSessionState ( ) ;
ss . Variables . Add ( BuiltInVariables ) ;
ss . Commands . Add ( new SessionStateApplicationEntry ( "*" ) ) ;
ss . Commands . Add ( new SessionStateScriptEntry ( "*" ) ) ;
ss . Commands . Add ( BuiltInFunctions ) ;
ss . Commands . Add ( BuiltInAliases ) ;
defaultSnapins = PSSnapInReader . ReadEnginePSSnapIns ( ) ;
foreach ( PSSnapInInfo si in defaultSnapins )
{
try
{
ss . ImportPSSnapIn ( si , out warning ) ;
}
catch ( PSSnapInException pse )
{
throw pse ;
}
#if DEBUG
//NOTE:
// This code is for testing a module-based shell. It is only available when the shell is complied
// in debug mode and is not intended to be a feature.
// July 31 2008 - brucepay
// Only load the core snapins at this point...
if ( Environment . GetEnvironmentVariable ( "PowerShellMinimal" ) ! = null )
{
2016-05-28 01:16:34 +02:00
if ( si . Name . Equals ( "Microsoft.PowerShell.Host" , StringComparison . OrdinalIgnoreCase ) )
2016-03-30 23:20:52 +02:00
break ;
}
#endif
}
// Remove duplicated assemblies
HashSet < string > assemblyList = new HashSet < string > ( ) ;
for ( int i = ss . Assemblies . Count - 1 ; i > = 0 ; i - - )
{
string assembly = ss . Assemblies [ i ] . FileName ;
if ( ! string . IsNullOrEmpty ( assembly ) )
{
if ( assemblyList . Contains ( assembly ) )
{
ss . Assemblies . RemoveItem ( i ) ;
}
else
{
assemblyList . Add ( assembly ) ;
}
}
}
ss . LanguageMode = PSLanguageMode . FullLanguage ;
ss . AuthorizationManager = new Microsoft . PowerShell . PSAuthorizationManager ( Utils . DefaultPowerShellShellID ) ;
return ss . Clone ( ) ;
}
/// <summary>
/// Creates the default PowerShell one with default cmdlets, provider etc.
/// The default cmdlets, provider, etc are loaded via Modules
/// </summary>
/// <returns></returns>
public static InitialSessionState CreateDefault2 ( )
{
InitialSessionState ss = new InitialSessionState ( ) ;
ss . Variables . Add ( BuiltInVariables ) ;
ss . Commands . Add ( new SessionStateApplicationEntry ( "*" ) ) ;
ss . Commands . Add ( new SessionStateScriptEntry ( "*" ) ) ;
ss . Commands . Add ( BuiltInFunctions ) ;
ss . Commands . Add ( BuiltInAliases ) ;
ss . ImportCorePSSnapIn ( ) ;
ss . LanguageMode = PSLanguageMode . FullLanguage ;
ss . AuthorizationManager = new Microsoft . PowerShell . PSAuthorizationManager ( Utils . DefaultPowerShellShellID ) ;
return ss . Clone ( ) ;
}
internal static bool IsEngineModule ( string moduleName )
{
return EngineModules . Contains ( moduleName ) | | NestedEngineModules . Contains ( moduleName ) ;
}
internal static bool IsNestedEngineModule ( string moduleName )
{
return NestedEngineModules . Contains ( moduleName ) ;
}
internal static bool IsConstantEngineModule ( string moduleName )
{
return ConstantEngineModules . Contains ( moduleName ) | | ConstantEngineNestedModules . Contains ( moduleName ) ;
}
/// <summary>
/// Clone this InitialSessionState object. The collections are
/// recursively cloned as well as the elements in the collections.
/// Note however, that the contents of the individual entries
/// are not deep-cloned. This is only an issue for variable
/// entries which may have reference types. These objects
/// will be added by reference rather than by value.
/// </summary>
/// <returns>The cloned object.</returns>
public InitialSessionState Clone ( )
{
InitialSessionState ss = new InitialSessionState ( ) ;
ss . Variables . Add ( this . Variables . Clone ( ) ) ;
ss . EnvironmentVariables . Add ( this . EnvironmentVariables . Clone ( ) ) ;
ss . Commands . Add ( this . Commands . Clone ( ) ) ;
ss . Assemblies . Add ( this . Assemblies . Clone ( ) ) ;
ss . Providers . Add ( this . Providers . Clone ( ) ) ;
ss . Types . Add ( this . Types . Clone ( ) ) ;
ss . Formats . Add ( this . Formats . Clone ( ) ) ;
2016-07-29 22:02:49 +02:00
foreach ( string startupScript in this . StartupScripts )
2016-03-30 23:20:52 +02:00
{
ss . StartupScripts . Add ( startupScript ) ;
}
foreach ( string unresolvedCommandsToExpose in this . UnresolvedCommandsToExpose )
{
ss . UnresolvedCommandsToExpose . Add ( unresolvedCommandsToExpose ) ;
}
foreach ( Hashtable dynamicVariableToDefine in this . DynamicVariablesToDefine )
{
ss . DynamicVariablesToDefine . Add ( dynamicVariableToDefine ) ;
}
foreach ( var pair in this . CommandModifications )
{
ss . CommandModifications . Add ( pair . Key , pair . Value ) ;
}
ss . DefaultCommandVisibility = this . DefaultCommandVisibility ;
ss . AuthorizationManager = this . AuthorizationManager ;
ss . LanguageMode = this . LanguageMode ;
ss . TranscriptDirectory = this . TranscriptDirectory ;
ss . UserDriveEnabled = this . UserDriveEnabled ;
ss . UserDriveUserName = this . UserDriveUserName ;
ss . UserDriveMaximumSize = this . UserDriveMaximumSize ;
2016-07-29 22:02:49 +02:00
if ( _wasExecutionPolicySet )
2016-03-30 23:20:52 +02:00
{
ss . ExecutionPolicy = this . ExecutionPolicy ;
}
ss . UseFullLanguageModeInDebugger = this . UseFullLanguageModeInDebugger ;
ss . ThreadOptions = this . ThreadOptions ;
ss . ThrowOnRunspaceOpenError = this . ThrowOnRunspaceOpenError ;
#if ! CORECLR // No ApartmentState In CoreCLR
ss . ApartmentState = this . ApartmentState ;
#endif
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
foreach ( ModuleSpecification modSpec in this . ModuleSpecificationsToImport )
{
ss . ModuleSpecificationsToImport . Add ( modSpec ) ;
}
foreach ( string mod in this . CoreModulesToImport )
{
ss . CoreModulesToImport . Add ( mod ) ;
}
ss . DisableFormatUpdates = this . DisableFormatUpdates ;
foreach ( var s in this . defaultSnapins )
{
ss . defaultSnapins . Add ( s ) ;
}
2016-08-02 22:29:09 +02:00
foreach ( var s in ImportedSnapins )
2016-03-30 23:20:52 +02:00
{
ss . ImportedSnapins . Add ( s . Key , s . Value ) ;
}
return ss ;
}
/// <summary>
/// Want to get away from SnapIn and console file. Have modules and assemblies instead.
/// Specify the registered SnapIn name or name collection
/// </summary>
/// <param name="snapInName"></param>
/// <returns></returns>
public static InitialSessionState Create ( string snapInName )
{
return new InitialSessionState ( ) ;
}
/// <summary>
///
/// </summary>
/// <param name="snapInNameCollection"></param>
/// <param name="warning"></param>
/// <returns></returns>
public static InitialSessionState Create ( string [ ] snapInNameCollection , out PSConsoleLoadException warning )
{
warning = null ;
return new InitialSessionState ( ) ;
}
//This one is for module. Can take only one module, and not collection
//public static InitialSessionState Create(Module);
//Specify the unregistered module/snapIn path or path collection
/// <summary>
///
/// </summary>
/// <param name="snapInPath"></param>
/// <param name="warnings"></param>
/// <returns></returns>
public static InitialSessionState CreateFrom ( string snapInPath , out PSConsoleLoadException warnings )
{
warnings = null ;
return new InitialSessionState ( ) ;
}
/// <summary>
///
/// </summary>
/// <param name="snapInPathCollection"></param>
/// <param name="warnings"></param>
/// <returns></returns>
public static InitialSessionState CreateFrom ( string [ ] snapInPathCollection , out PSConsoleLoadException warnings )
{
warnings = null ;
return new InitialSessionState ( ) ;
}
/// <summary>
/// Specifies the language mode to be used for this session state instance
/// </summary>
2016-08-02 22:29:09 +02:00
public PSLanguageMode LanguageMode { get ; set ; } = PSLanguageMode . NoLanguage ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// Specifies the directory to be used for collection session transcripts
/// </summary>
2016-08-02 22:29:09 +02:00
public string TranscriptDirectory { get ; set ; } = null ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// True when session opted for a User PSDrive.
/// </summary>
internal bool UserDriveEnabled
{
get ;
set ;
}
/// <summary>
/// User name for the user drive. This will be part of the root path
/// for the User PSDrive.
/// </summary>
internal string UserDriveUserName
{
get ;
set ;
}
/// <summary>
/// Optional maximum size value for User drive (in bytes).
/// </summary>
internal long UserDriveMaximumSize
{
get ;
set ;
}
/// <summary>
/// Forces all session script input parameters to have validation.
/// </summary>
internal bool EnforceInputParameterValidation
{
get ;
set ;
}
/// <summary>
/// Specifies the execution policy to be used for this session state instance
/// </summary>
public Microsoft . PowerShell . ExecutionPolicy ExecutionPolicy
{
get { return _executionPolicy ; }
set
{
_executionPolicy = value ;
_wasExecutionPolicySet = true ;
}
}
private Microsoft . PowerShell . ExecutionPolicy _executionPolicy = Microsoft . PowerShell . ExecutionPolicy . Default ;
private bool _wasExecutionPolicySet = false ;
/// <summary>
/// If true the PowerShell debugger will use FullLanguage mode, otherwise it will use the current language mode
/// </summary>
2016-08-02 22:29:09 +02:00
public bool UseFullLanguageModeInDebugger { get ; set ; } = false ;
2016-03-30 23:20:52 +02:00
#if ! CORECLR // No ApartmentState In CoreCLR
/// <summary>
/// ApartmentState of the thread used to execute commands
/// </summary>
2016-08-02 22:29:09 +02:00
public ApartmentState ApartmentState { get ; set ; } = Runspace . DefaultApartmentState ;
2016-03-30 23:20:52 +02:00
#endif
/// <summary>
/// This property determines whether a new thread is create for each invocation of a command
/// </summary>
2016-08-02 22:29:09 +02:00
public PSThreadOptions ThreadOptions { get ; set ; } = PSThreadOptions . Default ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// If this property is set and there was a runspace creation error, then
/// throw an exception, otherwise just continue creating the runspace even though it may
/// be in an inconsistent state.
/// </summary>
2016-08-02 22:29:09 +02:00
public bool ThrowOnRunspaceOpenError { get ; set ; } = false ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// This property will be set only if we are refreshing the Type/Format settings by calling UpdateTypes/UpdateFormats directly.
/// In this case, we should wait until all type/format entries get processed. After that, if there were errors
/// generated, we throw them as an exception.
/// </summary>
internal bool RefreshTypeAndFormatSetting = false ;
/// <summary>
/// Specifies the authorization manager to be used for this session state instance.
/// If no authorization manager is specified, then the default authroization manager
/// for PowerShell will be used which checks the ExecutionPolicy before running a command.
/// </summary>
2016-08-02 22:29:09 +02:00
public virtual AuthorizationManager AuthorizationManager { get ; set ; } = new Microsoft . PowerShell . PSAuthorizationManager ( Utils . DefaultPowerShellShellID ) ;
2016-03-30 23:20:52 +02:00
internal PSHost Host = null ;
/// <summary>
/// Add a list of modules to import when the runspace is created.
/// </summary>
/// <param name="name">The modules to add</param>
/// <returns></returns>
public void ImportPSModule ( string [ ] name )
{
if ( name = = null )
throw new ArgumentNullException ( "name" ) ;
foreach ( string n in name )
{
2016-08-02 22:29:09 +02:00
ModuleSpecificationsToImport . Add ( new ModuleSpecification ( n ) ) ;
2016-03-30 23:20:52 +02:00
}
}
/// <summary>
/// Clears ImportPSModule list.
/// </summary>
internal void ClearPSModules ( )
{
2016-08-02 22:29:09 +02:00
ModuleSpecificationsToImport . Clear ( ) ;
2016-03-30 23:20:52 +02:00
}
/// <summary>
/// Add a list of modules to import when the runspace is created.
/// </summary>
/// <param name="modules">
/// The modules, whose specificiations are specified by <paramref name="modules"/>,
/// to add.
/// </param>
public void ImportPSModule ( IEnumerable < ModuleSpecification > modules )
{
if ( modules = = null )
{
throw new ArgumentNullException ( "modules" ) ;
}
foreach ( var moduleSpecification in modules )
{
2016-08-02 22:29:09 +02:00
ModuleSpecificationsToImport . Add ( moduleSpecification ) ;
2016-03-30 23:20:52 +02:00
}
}
/// <summary>
/// Imports all the modules from the specified module
/// path by default
/// </summary>
/// <param name="path">path from which all modules need
/// to be imported</param>
public void ImportPSModulesFromPath ( string path )
{
string expandedpath = Environment . ExpandEnvironmentVariables ( path ) ;
var availableModuleFiles = ModuleUtils . GetDefaultAvailableModuleFiles ( expandedpath ) ;
ImportPSModule ( availableModuleFiles . ToArray ( ) ) ;
}
/// <summary>
/// Add a list of core modules to import when the runspace is created.
/// </summary>
/// <param name="name">The modules to add</param>
/// <returns></returns>
internal void ImportPSCoreModule ( string [ ] name )
{
if ( name = = null )
throw new ArgumentNullException ( "name" ) ;
foreach ( string n in name )
{
2016-08-02 22:29:09 +02:00
CoreModulesToImport . Add ( n ) ;
2016-03-30 23:20:52 +02:00
}
}
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
/// <summary>
/// Imported modules.
/// </summary>
public ReadOnlyCollection < ModuleSpecification > Modules
{
2016-08-02 22:29:09 +02:00
get { return new ReadOnlyCollection < ModuleSpecification > ( ModuleSpecificationsToImport ) ; }
2016-03-30 23:20:52 +02:00
}
2016-08-02 22:29:09 +02:00
internal Collection < ModuleSpecification > ModuleSpecificationsToImport { get ; } = new Collection < ModuleSpecification > ( ) ;
2016-03-30 23:20:52 +02:00
2016-08-02 22:29:09 +02:00
internal Dictionary < string , PSSnapInInfo > ImportedSnapins { get ; } = new Dictionary < string , PSSnapInInfo > ( StringComparer . OrdinalIgnoreCase ) ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// Gets the dictionary of core modules to import on runspace creation...
/// </summary>
2016-08-02 22:29:09 +02:00
internal HashSet < string > CoreModulesToImport { get ; } = new HashSet < string > ( ) ;
2016-03-30 23:20:52 +02:00
/// <summary>
/// The list of assemblies to load...
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateAssemblyEntry > Assemblies
{
get
{
if ( _assemblies = = null )
Interlocked . CompareExchange ( ref _assemblies , new InitialSessionStateEntryCollection < SessionStateAssemblyEntry > ( ) , null ) ;
return _assemblies ;
}
}
private InitialSessionStateEntryCollection < SessionStateAssemblyEntry > _assemblies ;
/// <summary>
/// List of types to use for this session state instance...
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateTypeEntry > Types
{
get
{
if ( _types = = null )
Interlocked . CompareExchange ( ref _types , new InitialSessionStateEntryCollection < SessionStateTypeEntry > ( ) , null ) ;
return _types ;
}
}
private InitialSessionStateEntryCollection < SessionStateTypeEntry > _types ;
/// <summary>
///
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateFormatEntry > Formats
{
get
{
if ( _formats = = null )
Interlocked . CompareExchange ( ref _formats , new InitialSessionStateEntryCollection < SessionStateFormatEntry > ( ) , null ) ;
return _formats ;
}
}
private InitialSessionStateEntryCollection < SessionStateFormatEntry > _formats ;
/// <summary>
/// If set to true, disables any updates to format table. This includes disabling
/// format table updates throught Update-FormatData, Import-Module etc.
/// All the disabling happens silently ie., the user will not get any exception.
/// By default, this is set to False.
/// </summary>
public bool DisableFormatUpdates { get ; set ; }
/// <summary>
///
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateProviderEntry > Providers
{
get
{
if ( _providers = = null )
Interlocked . CompareExchange ( ref _providers , new InitialSessionStateEntryCollection < SessionStateProviderEntry > ( ) , null ) ;
return _providers ;
}
}
private InitialSessionStateEntryCollection < SessionStateProviderEntry > _providers ;
/// <summary>
/// List of commands (Alias, Application, Cmdlets, Function, Script) for this entry.
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateCommandEntry > Commands
{
get
{
if ( _commands = = null )
Interlocked . CompareExchange ( ref _commands , new InitialSessionStateEntryCollection < SessionStateCommandEntry > ( ) , null ) ;
return _commands ;
}
}
private InitialSessionStateEntryCollection < SessionStateCommandEntry > _commands ;
internal SessionStateEntryVisibility DefaultCommandVisibility { get ; set ; }
internal HashSet < string > UnresolvedCommandsToExpose
{
get
{
if ( _unresolvedCommandsToExpose = = null )
Interlocked . CompareExchange ( ref _unresolvedCommandsToExpose , new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) , null ) ;
return _unresolvedCommandsToExpose ;
}
}
private HashSet < string > _unresolvedCommandsToExpose ;
internal Dictionary < string , Hashtable > CommandModifications
{
get
{
if ( _commandModifications = = null )
Interlocked . CompareExchange ( ref _commandModifications , new Dictionary < string , Hashtable > ( StringComparer . OrdinalIgnoreCase ) , null ) ;
return _commandModifications ;
}
}
private Dictionary < string , Hashtable > _commandModifications ;
internal List < Hashtable > DynamicVariablesToDefine
{
get
{
if ( _dynamicVariablesToDefine = = null )
Interlocked . CompareExchange ( ref _dynamicVariablesToDefine , new List < Hashtable > ( ) , null ) ;
return _dynamicVariablesToDefine ;
}
}
private List < Hashtable > _dynamicVariablesToDefine ;
/// <summary>
///
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateVariableEntry > Variables
{
get
{
if ( _variables = = null )
Interlocked . CompareExchange ( ref _variables , new InitialSessionStateEntryCollection < SessionStateVariableEntry > ( ) , null ) ;
return _variables ;
}
}
private InitialSessionStateEntryCollection < SessionStateVariableEntry > _variables ;
/// <summary>
///
/// </summary>
public virtual InitialSessionStateEntryCollection < SessionStateVariableEntry > EnvironmentVariables
{
get
{
if ( _environmentVariables = = null )
Interlocked . CompareExchange ( ref _environmentVariables , new InitialSessionStateEntryCollection < SessionStateVariableEntry > ( ) , null ) ;
return _environmentVariables ;
}
}
private InitialSessionStateEntryCollection < SessionStateVariableEntry > _environmentVariables ;
/// <summary>
///
/// </summary>
public virtual HashSet < String > StartupScripts
{
get
{
if ( _startupScripts = = null )
Interlocked . CompareExchange ( ref _startupScripts , new HashSet < String > ( ) , null ) ;
return _startupScripts ;
}
}
private HashSet < String > _startupScripts = new HashSet < string > ( ) ;
2016-07-29 22:02:49 +02:00
private Object _syncObject = new Object ( ) ;
2016-03-30 23:20:52 +02:00
internal void Bind ( ExecutionContext context , bool updateOnly )
{
Bind ( context , updateOnly , null , /*noClobber*/ false , /*local*/ false ) ;
}
internal void Bind ( ExecutionContext context , bool updateOnly , PSModuleInfo module , bool noClobber , bool local )
{
Host = context . EngineHostInterface ;
lock ( _syncObject )
{
SessionStateInternal ss = context . EngineSessionState ;
// Clear the application and script collections...
if ( ! updateOnly )
{
ss . Applications . Clear ( ) ;
ss . Scripts . Clear ( ) ;
}
// If the initial session state made some commands private by way of
// VisibleCmdlets / etc., then change the default command visibility for
// the sesssion state so that newly imported modules aren't exposed accidentally.
if ( DefaultCommandVisibility = = SessionStateEntryVisibility . Private )
{
ss . DefaultCommandVisibility = SessionStateEntryVisibility . Private ;
}
try
{
// Load assemblies before anything else - we may need to resolve types in the loaded
// assemblies as part of loading formats or types, and that can't be done in parallel.
Bind_LoadAssemblies ( context ) ;
var actions = new Action [ ]
{
( ) = > Bind_UpdateTypes ( context , updateOnly ) ,
( ) = > Bind_UpdateFormats ( context , updateOnly ) ,
( ) = > Bind_BindCommands ( module , noClobber , local , ss ) ,
( ) = > Bind_LoadProviders ( ss ) ,
( ) = > Bind_SetVariables ( ss ) ,
Bind_SetEnvironment
} ;
if ( updateOnly )
{
// We're typically called to import a module. It seems like this could
// still happen in parallel, but calls to WriteError on the wrong thread
// get silently swallowed, so instead just run the actions serially on this thread.
foreach ( var action in actions )
{
action ( ) ;
}
}
else
{
Parallel . Invoke ( actions ) ;
}
}
catch ( AggregateException e )
{
e = e . Flatten ( ) ;
foreach ( var exception in e . InnerExceptions )
{
MshLog . LogEngineHealthEvent (
context ,
MshLog . EVENT_ID_CONFIGURATION_FAILURE ,
exception ,
Severity . Warning ) ;
}
if ( this . ThrowOnRunspaceOpenError )
{
// Just throw the first error
throw e . InnerExceptions [ 0 ] ;
}
context . ReportEngineStartupError ( e . Message ) ;
}
catch ( Exception e )
{
MshLog . LogEngineHealthEvent (
context ,
MshLog . EVENT_ID_CONFIGURATION_FAILURE ,
e ,
Severity . Warning ) ;
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
if ( this . ThrowOnRunspaceOpenError )
{
throw ;
}
context . ReportEngineStartupError ( e . Message ) ;
}
// Set the language mode
if ( ! updateOnly )
{
ss . LanguageMode = LanguageMode ;
}
// Set the execution policy
if ( _wasExecutionPolicySet )
{
string shellId = context . ShellID ;
SecuritySupport . SetExecutionPolicy ( Microsoft . PowerShell . ExecutionPolicyScope . Process , ExecutionPolicy , shellId ) ;
}
}
2016-07-29 22:02:49 +02:00
SetSessionStateDrive ( context , setLocation : false ) ;
2016-03-30 23:20:52 +02:00
}
private void Bind_SetVariables ( SessionStateInternal ss )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . LoadVariablesStart ( ) ;
// Add all of the variables to session state...
foreach ( SessionStateVariableEntry var in Variables )
{
ss . AddSessionStateEntry ( var ) ;
}
if ( etwEnabled ) RunspaceEventSource . Log . LoadVariablesStop ( ) ;
}
private void Bind_SetEnvironment ( )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . LoadEnvironmentVariablesStart ( ) ;
foreach ( SessionStateVariableEntry var in EnvironmentVariables )
{
Environment . SetEnvironmentVariable ( var . Name , var . Value . ToString ( ) ) ;
}
if ( etwEnabled ) RunspaceEventSource . Log . LoadEnvironmentVariablesStop ( ) ;
}
private void Bind_UpdateTypes ( ExecutionContext context , bool updateOnly )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . UpdateTypeTableStart ( ) ;
this . UpdateTypes ( context , updateOnly ) ;
if ( etwEnabled ) RunspaceEventSource . Log . UpdateTypeTableStop ( ) ;
}
private void Bind_UpdateFormats ( ExecutionContext context , bool updateOnly )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . UpdateFormatTableStart ( ) ;
this . UpdateFormats ( context , updateOnly ) ;
if ( etwEnabled ) RunspaceEventSource . Log . UpdateFormatTableStop ( ) ;
}
private void Bind_LoadProviders ( SessionStateInternal ss )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . LoadProvidersStart ( ) ;
// Add all of the providers to session state...
foreach ( SessionStateProviderEntry provider in Providers )
{
if ( etwEnabled ) RunspaceEventSource . Log . LoadProviderStart ( provider . Name ) ;
ss . AddSessionStateEntry ( provider ) ;
if ( etwEnabled ) RunspaceEventSource . Log . LoadProviderStop ( provider . Name ) ;
}
if ( etwEnabled ) RunspaceEventSource . Log . LoadProvidersStop ( ) ;
}
private void Bind_BindCommands ( PSModuleInfo module , bool noClobber , bool local , SessionStateInternal ss )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . LoadCommandsStart ( ) ;
#if ! CORECLR // Workflow Not Supported On CSS
InitialSessionState cloneForWorkflowDefinitions = null ;
#endif
foreach ( SessionStateCommandEntry cmd in Commands )
{
if ( etwEnabled ) RunspaceEventSource . Log . LoadCommandStart ( cmd . Name ) ;
SessionStateCmdletEntry ssce = cmd as SessionStateCmdletEntry ;
if ( ssce ! = null )
{
if ( noClobber & & ModuleCmdletBase . CommandFound ( ssce . Name , ss ) )
{
ssce . _isImported = false ;
continue ;
}
ss . AddSessionStateEntry ( ssce , local ) ;
cmd . SetModule ( module ) ;
continue ;
}
cmd . SetModule ( module ) ;
SessionStateFunctionEntry ssfe = cmd as SessionStateFunctionEntry ;
if ( ssfe ! = null )
{
ss . AddSessionStateEntry ( ssfe ) ;
continue ;
}
SessionStateAliasEntry ssae = cmd as SessionStateAliasEntry ;
if ( ssae ! = null )
{
ss . AddSessionStateEntry ( ssae , StringLiterals . Local ) ;
continue ;
}
SessionStateApplicationEntry ssappe = cmd as SessionStateApplicationEntry ;
if ( ssappe ! = null )
{
if ( ssappe . Visibility = = SessionStateEntryVisibility . Public )
{
ss . AddSessionStateEntry ( ssappe ) ;
}
continue ;
}
SessionStateScriptEntry ssse = cmd as SessionStateScriptEntry ;
if ( ssse ! = null )
{
if ( ssse . Visibility = = SessionStateEntryVisibility . Public )
{
ss . AddSessionStateEntry ( ssse ) ;
}
continue ;
}
#if ! CORECLR // Workflow Not Supported On CSS
SessionStateWorkflowEntry sswe = cmd as SessionStateWorkflowEntry ;
if ( sswe ! = null )
{
if ( cloneForWorkflowDefinitions = = null )
{
cloneForWorkflowDefinitions = this . Clone ( ) ;
var commandsCopy =
cloneForWorkflowDefinitions . Commands . Where ( e = > ! ( e is SessionStateWorkflowEntry ) )
. ToList ( ) ;
cloneForWorkflowDefinitions . Commands . Clear ( ) ;
foreach ( var c in commandsCopy )
{
cloneForWorkflowDefinitions . Commands . Add ( c ) ;
}
}
ss . AddSessionStateEntry ( cloneForWorkflowDefinitions , sswe ) ;
}
#endif
if ( etwEnabled ) RunspaceEventSource . Log . LoadCommandStop ( cmd . Name ) ;
}
if ( etwEnabled ) RunspaceEventSource . Log . LoadCommandsStop ( ) ;
}
private void Bind_LoadAssemblies ( ExecutionContext context )
{
bool etwEnabled = RunspaceEventSource . Log . IsEnabled ( ) ;
if ( etwEnabled ) RunspaceEventSource . Log . LoadAssembliesStart ( ) ;
// Load the assemblies and initialize the assembly cache...
foreach ( SessionStateAssemblyEntry ssae in Assemblies )
{
if ( etwEnabled ) RunspaceEventSource . Log . LoadAssemblyStart ( ssae . Name , ssae . FileName ) ;
Exception error = null ;
Assembly asm = context . AddAssembly ( ssae . Name , ssae . FileName , out error ) ;
if ( asm = = null | | error ! = null )
{
// If no module was found but there was no specific error, then
// create a not found error.
if ( error = = null )
{
string msg = StringUtil . Format ( global :: Modules . ModuleAssemblyFound , ssae . Name ) ;
error = new DllNotFoundException ( msg ) ;
}
// If this occurs while loading a module manifest, just
// throw the exception instead of writing it out...
if ( ( ! string . IsNullOrEmpty ( context . ModuleBeingProcessed ) & &
Path . GetExtension ( context . ModuleBeingProcessed )
. Equals ( StringLiterals . PowerShellDataFileExtension ,
StringComparison . OrdinalIgnoreCase ) ) | |
2016-08-02 22:29:09 +02:00
ThrowOnRunspaceOpenError )
2016-03-30 23:20:52 +02:00
{
throw error ;
}
else
{
context . ReportEngineStartupError ( error . Message ) ;
}
}
if ( etwEnabled ) RunspaceEventSource . Log . LoadAssemblyStop ( ssae . Name , ssae . FileName ) ;
}
if ( etwEnabled ) RunspaceEventSource . Log . LoadAssembliesStop ( ) ;
}
internal Exception BindRunspace ( Runspace initializedRunspace , PSTraceSource runspaceInitTracer )
{
// Get initial list of public commands in session.
HashSet < CommandInfo > publicCommands = new HashSet < CommandInfo > ( ) ;
foreach ( CommandInfo sessionCommand in initializedRunspace . ExecutionContext . SessionState . InvokeCommand . GetCommands (
2016-04-28 22:41:25 +02:00
"*" , CommandTypes . Alias | CommandTypes . Function | CommandTypes . Filter | CommandTypes . Cmdlet , true ) )
2016-03-30 23:20:52 +02:00
{
if ( sessionCommand . Visibility = = SessionStateEntryVisibility . Public )
{
publicCommands . Add ( sessionCommand ) ;
}
}
// If a user has any module with the same name as that of the core module( or nested module inside the core module)
// in his module path, then that will get loaded instead of the actual nested module (from the GAC - in our case)
// Hence, searching only from the system module path while loading the core modules
ProcessImportModule ( initializedRunspace , CoreModulesToImport , ModuleIntrinsics . GetSystemwideModulePath ( ) , publicCommands ) ;
// Win8:328748 - functions defined in global scope end up in a module
// Since we import the core modules, EngineSessionState's module is set to the last imported module. So, if a function is defined in global scope, it ends up in that module.
// Setting the module to null fixes that.
initializedRunspace . ExecutionContext . EngineSessionState . Module = null ;
// Set the SessionStateDrive here since we have all the provider information at this point
SetSessionStateDrive ( initializedRunspace . ExecutionContext , true ) ;
Exception moduleImportException = ProcessImportModule ( initializedRunspace , ModuleSpecificationsToImport , "" , publicCommands ) ;
2016-07-29 22:02:49 +02:00
if ( moduleImportException ! = null )
2016-03-30 23:20:52 +02:00
{
runspaceInitTracer . WriteLine (
"Runspace open failed while loading module: First error {1}" , moduleImportException ) ;
return moduleImportException ;
}
// If we still have unresolved commands after importing specified modules, then try finding associated module for
// each unresolved command and import that module.
string [ ] foundModuleList = GetModulesForUnResolvedCommands ( UnresolvedCommandsToExpose , initializedRunspace . ExecutionContext ) ;
if ( foundModuleList . Length > 0 )
{
ProcessImportModule ( initializedRunspace , foundModuleList , "" , publicCommands ) ;
}
ProcessDynamicVariables ( initializedRunspace ) ;
ProcessCommandModifications ( initializedRunspace ) ;
// Process User: drive
Exception userDriveException = ProcessUserDrive ( initializedRunspace ) ;
if ( userDriveException ! = null )
{
runspaceInitTracer . WriteLine (
"Runspace open failed while processing user drive with error {1}" , userDriveException ) ;
Exception result = PSTraceSource . NewInvalidOperationException ( userDriveException , RemotingErrorIdStrings . UserDriveProcessingThrewTerminatingError , userDriveException . Message ) ;
return result ;
}
// Process startup scripts
Exception startupScriptException = ProcessStartupScripts ( initializedRunspace ) ;
if ( startupScriptException ! = null )
{
runspaceInitTracer . WriteLine (
"Runspace open failed while running startup script: First error {1}" , startupScriptException ) ;
Exception result = PSTraceSource . NewInvalidOperationException ( startupScriptException , RemotingErrorIdStrings . StartupScriptThrewTerminatingError , startupScriptException . Message ) ;
return result ;
}
// Start transcribing
2016-07-29 22:02:49 +02:00
if ( ! String . IsNullOrEmpty ( TranscriptDirectory ) )
2016-03-30 23:20:52 +02:00
{
using ( PowerShell psToInvoke = PowerShell . Create ( ) )
{
psToInvoke . AddCommand ( new Command ( "Start-Transcript" ) ) . AddParameter ( "OutputDirectory" , TranscriptDirectory ) ;
Exception exceptionToReturn = ProcessPowerShellCommand ( psToInvoke , initializedRunspace ) ;
if ( exceptionToReturn ! = null )
{
// ThrowOnRunspaceOpenError handling is done by ProcessPowerShellCommand
return exceptionToReturn ;
}
}
}
return null ;
}
private string [ ] GetModulesForUnResolvedCommands ( IEnumerable < string > unresolvedCommands , ExecutionContext context )
{
Collection < string > modulesToImport = new Collection < string > ( ) ;
HashSet < string > commandsToResolve = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
foreach ( var unresolvedCommand in unresolvedCommands )
{
string moduleName ;
string command = Utils . ParseCommandName ( unresolvedCommand , out moduleName ) ;
if ( ! string . IsNullOrEmpty ( moduleName ) )
{
// Skip fully qualified module names since they are already processed.
continue ;
}
if ( WildcardPattern . ContainsWildcardCharacters ( command ) )
{
// Skip names with wild cards.
continue ;
}
commandsToResolve . Add ( command ) ;
}
if ( commandsToResolve . Count > 0 )
{
Runspace restoreRunspace = Runspace . DefaultRunspace ;
try
{
// Create a temporary default runspace for the analysis cache to use.
using ( Runspace tempRunspace = RunspaceFactory . CreateRunspace ( ) )
{
tempRunspace . Open ( ) ;
Runspace . DefaultRunspace = tempRunspace ;
foreach ( var unresolvedCommand in commandsToResolve )
{
// Use the analysis cache to find the first module containing the unresolved command.
foreach ( string modulePath in ModuleUtils . GetDefaultAvailableModuleFiles ( true , true , context ) )
{
string expandedModulePath = IO . Path . GetFullPath ( modulePath ) ;
var exportedCommands = AnalysisCache . GetExportedCommands ( expandedModulePath , false , context ) ;
if ( exportedCommands ! = null & & exportedCommands . ContainsKey ( unresolvedCommand ) )
{
modulesToImport . Add ( System . IO . Path . GetFileNameWithoutExtension ( expandedModulePath ) ) ;
break ;
}
}
}
}
}
finally
{
Runspace . DefaultRunspace = restoreRunspace ;
}
}
return modulesToImport . ToArray < string > ( ) ;
}
private void ProcessCommandModifications ( Runspace initializedRunspace )
{
2016-07-29 22:02:49 +02:00
foreach ( var pair in CommandModifications )
2016-03-30 23:20:52 +02:00
{
string commandName = pair . Key ;
Hashtable commandModification = pair . Value ;
CommandInfo existingCommand = initializedRunspace . SessionStateProxy . InvokeCommand . GetCommand ( commandName , CommandTypes . Cmdlet | CommandTypes . Function ) ;
2016-07-29 22:02:49 +02:00
if ( existingCommand = = null )
2016-03-30 23:20:52 +02:00
{
// Could not find the command - just continue, rather than generating an error. This could just be a missing module
// or something similar.
continue ;
}
// If we are wrapping a function, rename it.
FunctionInfo commandAsFunction = existingCommand as FunctionInfo ;
2016-07-29 22:02:49 +02:00
if ( commandAsFunction ! = null )
2016-03-30 23:20:52 +02:00
{
string newCommandName = commandAsFunction . Name + "_" + Guid . NewGuid ( ) . ToString ( "N" ) ;
commandAsFunction . Rename ( newCommandName ) ;
initializedRunspace . ExecutionContext . EngineSessionState . GlobalScope . FunctionTable . Add ( newCommandName , commandAsFunction ) ;
initializedRunspace . ExecutionContext . EngineSessionState . GlobalScope . FunctionTable . Remove ( commandName ) ;
existingCommand = initializedRunspace . SessionStateProxy . InvokeCommand . GetCommand ( newCommandName , CommandTypes . Function ) ;
}
CommandMetadata metadata = new CommandMetadata ( existingCommand ) ;
List < string > unprocessedCommandModifications = new List < string > ( ) ;
foreach ( string commandModificationParameter in commandModification . Keys )
{
unprocessedCommandModifications . Add ( commandModificationParameter ) ;
}
// Visit all parameters of the command we're wrapping
2016-07-29 22:02:49 +02:00
foreach ( string existingParameter in metadata . Parameters . Keys . ToArray < string > ( ) )
2016-03-30 23:20:52 +02:00
{
// If it's not allowed, remove it
2016-07-29 22:02:49 +02:00
if ( ! commandModification . ContainsKey ( existingParameter ) )
2016-03-30 23:20:52 +02:00
{
metadata . Parameters . Remove ( existingParameter ) ;
}
else
{
// Remember that we've processed this parameter, so that we can add the remainder
// as virtual command modifications over (what we must assume to be) dynamic parameters.
unprocessedCommandModifications . Remove ( existingParameter ) ;
ProcessCommandModification ( commandModification , metadata , existingParameter ) ;
}
}
// Now, process the command modifications that the user requested (but there was no parameter
// in the cmdlet that matched the requested parameter)
foreach ( string unprocessedCommandModification in unprocessedCommandModifications )
{
ProcessCommandModification ( commandModification , metadata , unprocessedCommandModification ) ;
}
string proxyBody = ProxyCommand . Create ( metadata , "" , false ) ;
ScriptBlock proxyScriptBlock = ScriptBlock . Create ( proxyBody ) ;
proxyScriptBlock . LanguageMode = PSLanguageMode . FullLanguage ;
initializedRunspace . ExecutionContext . EngineSessionState . GlobalScope . FunctionTable . Add (
commandName , new FunctionInfo ( commandName , proxyScriptBlock , initializedRunspace . ExecutionContext ) ) ;
}
}
/// <summary>
/// Process a command modification for a specific parameter
/// </summary>
/// <param name="commandModification">The hashtable of command modifications for this command</param>
/// <param name="metadata">The metadata for the command being processed</param>
/// <param name="parameterName">The parameter being modified</param>
private static void ProcessCommandModification ( Hashtable commandModification , CommandMetadata metadata , string parameterName )
{
// If the metadata doesn't actually contain the parameter, then we need to create one.
2016-07-29 22:02:49 +02:00
if ( ! metadata . Parameters . ContainsKey ( parameterName ) )
2016-03-30 23:20:52 +02:00
{
metadata . Parameters [ parameterName ] = new ParameterMetadata ( parameterName ) ;
}
// Add validation attributes
Hashtable parameterValidations = ( Hashtable ) commandModification [ parameterName ] ;
foreach ( object parameterValidation in parameterValidations . Keys )
{
string [ ] parameterValidationValues =
( ( HashSet < string > ) parameterValidations [ parameterValidation ] ) . ToList < string > ( ) . ToArray ( ) ;
switch ( parameterValidation . ToString ( ) )
{
case "ValidateSet" :
ValidateSetAttribute validateSet = new ValidateSetAttribute ( parameterValidationValues ) ;
metadata . Parameters [ parameterName ] . Attributes . Add ( validateSet ) ;
break ;
case "ValidatePattern" :
string pattern = "^(" + String . Join ( "|" , parameterValidationValues ) + ")$" ;
ValidatePatternAttribute validatePattern = new ValidatePatternAttribute ( pattern ) ;
metadata . Parameters [ parameterName ] . Attributes . Add ( validatePattern ) ;
break ;
}
}
}
private Exception ProcessDynamicVariables ( Runspace initializedRunspace )
{
foreach ( Hashtable variable in DynamicVariablesToDefine )
{
if ( variable . ContainsKey ( "Name" ) )
{
string name = variable [ "Name" ] . ToString ( ) ;
ScriptBlock sb = variable [ "Value" ] as ScriptBlock ;
if ( ! String . IsNullOrEmpty ( name ) & & ( sb ! = null ) )
{
sb . SessionStateInternal = initializedRunspace . ExecutionContext . EngineSessionState ;
using ( PowerShell psToInvoke = PowerShell . Create ( ) )
{
psToInvoke . AddCommand ( new Command ( "Invoke-Command" ) ) . AddParameter ( "ScriptBlock" , sb ) . AddParameter ( "NoNewScope" ) ;
psToInvoke . AddCommand ( new Command ( "Set-Variable" ) ) . AddParameter ( "Name" , name ) ;
Exception exceptionToReturn = ProcessPowerShellCommand ( psToInvoke , initializedRunspace ) ;
if ( exceptionToReturn ! = null )
{
// ThrowOnRunspaceOpenError handling is done by ProcessPowerShellCommand
return exceptionToReturn ;
}
}
}
}
}
return null ;
}
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
private Exception ProcessUserDrive ( Runspace initializedRunspace )
{
if ( ! UserDriveEnabled ) { return null ; }
Exception ex = null ;
try
{
List < ProviderInfo > fileSystemProviders = initializedRunspace . ExecutionContext . EngineSessionState . Providers [ "FileSystem" ] ;
if ( fileSystemProviders . Count = = 0 )
{
throw new PSInvalidOperationException ( RemotingErrorIdStrings . UserDriveCannotGetFileSystemProvider ) ;
}
// Create the User drive path directory in current user local appdata location:
// SystemDrive\Users\[user]\AppData\Local\Microsoft\Windows\PowerShell\DriveRoots\[UserName]
// Or for virtual accounts
// WinDir\System32\Microsoft\Windows\PowerShell\DriveRoots\[UserName]
string directoryName = MakeUserNamePath ( ) ;
string userDrivePath = Path . Combine (
Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ,
@"Microsoft\Windows\PowerShell\DriveRoots" ,
directoryName ) ;
// Create directory if it doesn't exist.
if ( ! System . IO . Directory . Exists ( userDrivePath ) )
{
System . IO . Directory . CreateDirectory ( userDrivePath ) ;
}
// Create the PSDrive.
var newDriveInfo = new PSDriveInfo (
"User" ,
fileSystemProviders [ 0 ] ,
userDrivePath ,
null ,
null ) ;
var userDriveInfo = initializedRunspace . ExecutionContext . SessionState . Drive . New ( newDriveInfo , null ) ;
// Set User drive maximum size. Default maximum size is 50MB
userDriveInfo . MaximumSize = ( UserDriveMaximumSize > 0 ) ? UserDriveMaximumSize : 50000000 ;
}
2016-07-29 22:02:49 +02:00
catch ( ArgumentNullException e ) { ex = e ; }
2016-03-30 23:20:52 +02:00
catch ( ArgumentException e ) { ex = e ; }
catch ( NotSupportedException e ) { ex = e ; }
catch ( ProviderNotFoundException e ) { ex = e ; }
catch ( ProviderInvocationException e ) { ex = e ; }
catch ( SessionStateOverflowException e ) { ex = e ; }
catch ( KeyNotFoundException e ) { ex = e ; }
catch ( IOException e ) { ex = e ; }
catch ( UnauthorizedAccessException e ) { ex = e ; }
return ex ;
}
private string MakeUserNamePath ( )
{
// Use the user name passsed to initial session state if avaiable, or
// otherwise use the current user name.
2016-07-29 22:02:49 +02:00
var userName = ( ! string . IsNullOrEmpty ( this . UserDriveUserName ) ) ?
2016-03-30 23:20:52 +02:00
this . UserDriveUserName :
System . Security . Principal . WindowsIdentity . GetCurrent ( ) . Name ;
// Ensure that user name contains no invalid path characters.
// MSDN indicates that logon names cannot contain any of these invalid characters,
// but this check will ensure safety.
if ( userName . IndexOfAny ( System . IO . Path . GetInvalidPathChars ( ) ) > - 1 )
{
throw new PSInvalidOperationException ( RemotingErrorIdStrings . InvalidUserDriveName ) ;
}
return userName . Replace ( "\\" , "_" ) ;
}
private Exception ProcessStartupScripts ( Runspace initializedRunspace )
{
foreach ( string startupScript in StartupScripts )
{
using ( PowerShell psToInvoke = PowerShell . Create ( ) )
{
psToInvoke . AddCommand ( new Command ( startupScript , false , false ) ) ;
Exception exceptionToReturn = ProcessPowerShellCommand ( psToInvoke , initializedRunspace ) ;
if ( exceptionToReturn ! = null )
{
// ThrowOnRunspaceOpenError handling is done by ProcessPowerShellCommand
return exceptionToReturn ;
}
}
}
return null ;
}
private Exception ProcessPowerShellCommand ( PowerShell psToInvoke , Runspace initializedRunspace )
{
PSLanguageMode originalLanguageMode = initializedRunspace . SessionStateProxy . LanguageMode ;
try
{
initializedRunspace . SessionStateProxy . LanguageMode = PSLanguageMode . FullLanguage ;
psToInvoke . Runspace = initializedRunspace ;
2016-07-29 22:02:49 +02:00
foreach ( Command command in psToInvoke . Commands . Commands )
2016-03-30 23:20:52 +02:00
{
command . CommandOrigin = CommandOrigin . Internal ;
}
try
{
psToInvoke . Invoke ( ) ;
}
catch ( Exception e )
{
CommandProcessorBase . CheckForSevereException ( e ) ;
if ( ThrowOnRunspaceOpenError )
{
return e ;
}
}
}
finally
{
// Restore the langauge mode, but not if it was altered by the startup script itself.
2016-07-29 22:02:49 +02:00
if ( initializedRunspace . SessionStateProxy . LanguageMode = = PSLanguageMode . FullLanguage )
2016-03-30 23:20:52 +02:00
{
initializedRunspace . SessionStateProxy . LanguageMode = originalLanguageMode ;
}
}
2016-07-29 22:02:49 +02:00
if ( ThrowOnRunspaceOpenError )
{
2016-03-30 23:20:52 +02:00
// find out if there are any error records reported. If there is one, report the error..
// this will result in the runspace getting closed/broken.
2016-07-29 22:02:49 +02:00
ArrayList errorList = ( ArrayList ) initializedRunspace . GetExecutionContext . DollarErrorVariable ;
2016-03-30 23:20:52 +02:00
if ( errorList . Count > 0 )
{
ErrorRecord lastErrorRecord = errorList [ 0 ] as ErrorRecord ;
if ( lastErrorRecord ! = null )
{
return new Exception ( lastErrorRecord . ToString ( ) ) ;
}
else
{
Exception lastException = errorList [ 0 ] as Exception ;
if ( lastException ! = null )
{
return lastException ;
}
else
{
return new Exception ( errorList [ 0 ] . ToString ( ) ) ;
}
}
}
}
return null ;
}
private RunspaceOpenModuleLoadException ProcessImportModule ( Runspace initializedRunspace , IEnumerable moduleList , string path , HashSet < CommandInfo > publicCommands )
{
RunspaceOpenModuleLoadException exceptionToReturn = null ;
foreach ( object module in moduleList )
{
string moduleName = module as string ;
if ( null ! = moduleName )
{
exceptionToReturn = ProcessImportModule ( initializedRunspace , moduleName , null , path , publicCommands ) ;
}
else
{
ModuleSpecification moduleSpecification = module as ModuleSpecification ;
if ( null ! = moduleSpecification )
{
if ( ( moduleSpecification . RequiredVersion = = null ) & & ( moduleSpecification . Version = = null ) & & ( moduleSpecification . MaximumVersion = = null ) & & ( moduleSpecification . Guid = = null ) )
{
// if only name is specified in the module spec, just try import the module
// ie., don't take the performance overhead of calling GetModule.
exceptionToReturn = ProcessImportModule ( initializedRunspace , moduleSpecification . Name , null , path , publicCommands ) ;
}
else
{
Collection < PSModuleInfo > moduleInfos = ModuleCmdletBase . GetModuleIfAvailable ( moduleSpecification , initializedRunspace ) ;
if ( moduleInfos ! = null & & moduleInfos . Count > 0 )
{
exceptionToReturn = ProcessImportModule ( initializedRunspace , moduleSpecification . Name , moduleInfos [ 0 ] , path , publicCommands ) ;
}
else
{
var version = "0.0.0.0" ;
if ( moduleSpecification . RequiredVersion ! = null )
{
version = moduleSpecification . RequiredVersion . ToString ( ) ;
}
else if ( moduleSpecification . Version ! = null )
2016-07-29 22:02:49 +02:00
{
2016-03-30 23:20:52 +02:00
version = moduleSpecification . Version . ToString ( ) ;
if ( moduleSpecification . MaximumVersion ! = null )
{
version = version + " - " + moduleSpecification . MaximumVersion ;
}
}
else if ( moduleSpecification . MaximumVersion ! = null )
{
version = moduleSpecification . MaximumVersion ;
}
string message = StringUtil . Format ( global :: Modules . RequiredModuleNotFoundWrongGuidVersion ,
moduleSpecification . Name ,
moduleSpecification . Guid ,
version ) ;
RunspaceOpenModuleLoadException rome = new RunspaceOpenModuleLoadException ( message ) ;
exceptionToReturn = ValidateAndReturnRunspaceOpenModuleLoadException ( null , moduleSpecification . Name , rome ) ;
}
}
}
else
{
Debug . Assert ( false , "ProcessImportModule can import a module using name or module specification." ) ;
}
}
}
if ( exceptionToReturn = = null )
{
// Now go through the list of commands not yet resolved to ensure they are public if requested
foreach ( string unresolvedCommand in UnresolvedCommandsToExpose . ToArray < string > ( ) )
{
string moduleName ;
string commandToMakeVisible = Utils . ParseCommandName ( unresolvedCommand , out moduleName ) ;
bool found = false ;
foreach ( CommandInfo cmd in LookupCommands ( commandToMakeVisible , moduleName , initializedRunspace . ExecutionContext ) )
{
if ( ! found ) { found = true ; }
try
{
// Special case for wild card lookups.
// "Import-Module" or "ipmo" cannot be visible when exposing commands via VisibleCmdlets, etc.
2016-07-29 22:02:49 +02:00
if ( ( cmd . Name . Equals ( "Import-Module" , StringComparison . OrdinalIgnoreCase ) & &
2016-03-30 23:20:52 +02:00
( ! string . IsNullOrEmpty ( cmd . ModuleName ) & & cmd . ModuleName . Equals ( "Microsoft.PowerShell.Core" , StringComparison . OrdinalIgnoreCase ) )
) | |
cmd . Name . Equals ( "ipmo" , StringComparison . OrdinalIgnoreCase )
)
{
cmd . Visibility = SessionStateEntryVisibility . Private ;
}
else
{
cmd . Visibility = SessionStateEntryVisibility . Public ;
publicCommands . Add ( cmd ) ;
}
}
// Some CommandInfo derivations throw on the Visibility setter.
catch ( PSNotImplementedException ) { }
}
if ( found & & ! WildcardPattern . ContainsWildcardCharacters ( commandToMakeVisible ) )
{
UnresolvedCommandsToExpose . Remove ( unresolvedCommand ) ;
}
}
}
return exceptionToReturn ;
}
/// <summary>
/// Helper method to search for commands matching the provided commandPattern.
/// Supports wild cards and if the commandPattern contains wildcard characters then multiple
/// results can be returned. Otherwise a single (and first) match will be returned.
/// If a moduleName is provided then only commands associated with that module will be returned.
/// Only public commands are searched to start with. If no results are found then a search on
/// internal commands is performed.
/// </summary>
/// <param name="commandPattern"></param>
/// <param name="moduleName"></param>
/// <param name="context"></param>
/// <returns></returns>
private IEnumerable < CommandInfo > LookupCommands (
2016-07-29 22:02:49 +02:00
string commandPattern ,
string moduleName ,
2016-03-30 23:20:52 +02:00
ExecutionContext context )
{
bool isWildCardPattern = WildcardPattern . ContainsWildcardCharacters ( commandPattern ) ;
var searchOptions = ( isWildCardPattern ) ?
SearchResolutionOptions . CommandNameIsPattern | SearchResolutionOptions . ResolveFunctionPatterns | SearchResolutionOptions . SearchAllScopes :
SearchResolutionOptions . ResolveFunctionPatterns | SearchResolutionOptions . SearchAllScopes ;
bool found = false ;
bool haveModuleName = ! string . IsNullOrEmpty ( moduleName ) ;
// Start with public search
CommandOrigin cmdOrigin = CommandOrigin . Runspace ;
while ( true )
{
foreach ( CommandInfo commandInfo in context . SessionState . InvokeCommand . GetCommands ( commandPattern , CommandTypes . All , searchOptions , cmdOrigin ) )
{
// If module name is provided then use it to restrict returned results.
if ( haveModuleName & & ! moduleName . Equals ( commandInfo . ModuleName , StringComparison . OrdinalIgnoreCase ) )
{
continue ;
}
if ( ! found ) { found = true ; }
yield return commandInfo ;
// Return first match unless a wild card pattern is submitted.
if ( ! isWildCardPattern ) { break ; }
}
2016-07-29 22:02:49 +02:00
if ( found | | ( cmdOrigin = = CommandOrigin . Internal ) )
{
2016-03-30 23:20:52 +02:00
break ;
}
// Next try internal search.
cmdOrigin = CommandOrigin . Internal ;
}
}
/// <summary>
/// if <paramref name="moduleInfoToLoad"/> is null, import module using <paramref name="name"/>. Otherwise,
/// import module using <paramref name="moduleInfoToLoad"/>
/// </summary>
private RunspaceOpenModuleLoadException ProcessImportModule ( Runspace initializedRunspace , string name , PSModuleInfo moduleInfoToLoad , string path , HashSet < CommandInfo > publicCommands )
{
using ( PowerShell pse = PowerShell . Create ( ) )
{
CommandInfo c = new CmdletInfo ( "Import-Module" , typeof ( ImportModuleCommand ) , null , null , initializedRunspace . ExecutionContext ) ;
Command cmd = new Command ( c ) ;
if ( null ! = moduleInfoToLoad )
{
cmd . Parameters . Add ( "ModuleInfo" , moduleInfoToLoad ) ;
name = moduleInfoToLoad . Name ;
}
else
{
// If FullyQualifiedPath is supplied then use it.
// In this scenario, the FullyQualifiedPath would
// refer to $pshome\Modules location where core
// modules are deployed.
if ( ! string . IsNullOrEmpty ( path ) )
{
name = Path . Combine ( path , name ) ;
}
cmd . Parameters . Add ( "Name" , name ) ;
}
2016-07-29 22:02:49 +02:00
if ( ! ThrowOnRunspaceOpenError )
2016-03-30 23:20:52 +02:00
{
cmd . MergeMyResults ( PipelineResultTypes . Error , PipelineResultTypes . Output ) ;
}
pse . AddCommand ( cmd ) ;
2016-07-29 22:02:49 +02:00
if ( ! ThrowOnRunspaceOpenError )
2016-03-30 23:20:52 +02:00
{
c = new CmdletInfo ( "Out-Default" , typeof ( OutDefaultCommand ) , null , null , initializedRunspace . ExecutionContext ) ;
pse . AddCommand ( new Command ( c ) ) ;
}
pse . Runspace = initializedRunspace ;
2016-04-01 02:27:44 +02:00
// Module import should be run in FullLanguage mode since it is running in
// a trusted context.
var savedLanguageMode = pse . Runspace . ExecutionContext . LanguageMode ;
pse . Runspace . ExecutionContext . LanguageMode = PSLanguageMode . FullLanguage ;
try
{
pse . Invoke ( ) ;
}
finally
{
pse . Runspace . ExecutionContext . LanguageMode = savedLanguageMode ;
}
2016-03-30 23:20:52 +02:00
// Lock down the command visibility to respect default command visibility
if ( this . DefaultCommandVisibility ! = SessionStateEntryVisibility . Public )
{
foreach ( CommandInfo importedCommand in initializedRunspace . ExecutionContext . SessionState . InvokeCommand . GetCommands (
2016-04-28 22:41:25 +02:00
"*" , CommandTypes . Alias | CommandTypes . Function | CommandTypes . Filter | CommandTypes . Cmdlet , true ) )
2016-03-30 23:20:52 +02:00
{
try
{
// All commands except for the initial session public commands should be made private.
2016-04-28 22:41:25 +02:00
if ( ( importedCommand . Visibility ! = this . DefaultCommandVisibility ) & &
2016-03-30 23:20:52 +02:00
! publicCommands . Contains ( importedCommand ) )
{
importedCommand . Visibility = this . DefaultCommandVisibility ;
}
}
// Some CommandInfo derivations throw on the Visibility setter.
catch ( PSNotImplementedException ) { }
}
}
// Now see if there were any errors. Because the only way we have to
// return an error at this point is a single exception, we'll take the first
// error and throw it...
return ValidateAndReturnRunspaceOpenModuleLoadException ( pse , name , null ) ;
}
}
private RunspaceOpenModuleLoadException ValidateAndReturnRunspaceOpenModuleLoadException ( PowerShell pse , string moduleName , RunspaceOpenModuleLoadException exception )
{
// Only throw the exception if ThrowOnRunspaceOpenError is set.
if ( ThrowOnRunspaceOpenError )
{
RunspaceOpenModuleLoadException rome = null ;
if ( exception ! = null )
{
rome = exception ;
}
else if ( pse . Streams . Error . Count > 0 )
{
ErrorRecord er ;
Exception firstError ;
// Merge errors from pse.Streams and errors
PSDataCollection < ErrorRecord > mergedErrors = new PSDataCollection < ErrorRecord > ( ) ;
er = pse . Streams . Error [ 0 ] ;
firstError = er . Exception ;
foreach ( var e in pse . Streams . Error )
{
mergedErrors . Add ( e ) ;
}
rome = new RunspaceOpenModuleLoadException ( moduleName , mergedErrors ) ;
}
if ( null ! = rome )
{
return rome ;
}
}
return null ;
}
/// <summary>
/// Reinitializes elements of the associated runspace to their initial values.
/// This allows for runspace reuse with minimal chance for contamination.
/// </summary>
/// <param name="context"></param>
internal void ResetRunspaceState ( ExecutionContext context )
{
lock ( _syncObject )
{
SessionStateInternal ss = context . EngineSessionState ;
// Reset the global variable table
ss . InitializeSessionStateInternalSpecialVariables ( true ) ;
// Add the built-in variables
foreach ( SessionStateVariableEntry e in InitialSessionState . BuiltInVariables )
{
PSVariable v = new PSVariable ( e . Name , e . Value ,
2016-07-29 22:02:49 +02:00
e . Options , e . Attributes , e . Description )
{ Visibility = e . Visibility } ;
2016-03-30 23:20:52 +02:00
ss . GlobalScope . SetVariable ( e . Name , v , false , true , ss , fastPath : true ) ;
}
ss . InitializeFixedVariables ( ) ;
// Then re-initialize it with variables to session state...
foreach ( SessionStateVariableEntry e in Variables )
{
PSVariable v = new PSVariable ( e . Name , e . Value ,
2016-07-29 22:02:49 +02:00
e . Options , e . Attributes , e . Description )
{ Visibility = e . Visibility } ;
2016-03-30 23:20:52 +02:00
ss . GlobalScope . SetVariable ( e . Name , v , false , true , ss , fastPath : true ) ;
}
InitialSessionState . CreateQuestionVariable ( context ) ;
// Reset the path for this runspace.
SetSessionStateDrive ( context , true ) ;
// Reset the event, transaction and debug managers.
context . ResetManagers ( ) ;
// Reset tracing/debugging to the off state.
context . PSDebugTraceLevel = 0 ;
context . PSDebugTraceStep = false ;
}
}
internal static void SetSessionStateDrive ( ExecutionContext context , bool setLocation )
{
// Set the starting location to the current process working directory
// Ignore any errors as the file system provider may not be loaded or
// a drive with the same name as the real file system drive may not have
// been mounted.
try
{
bool proceedWithSetLocation = true ;
if ( context . EngineSessionState . ProviderCount > 0 )
{
// NTRAID#Windows Out Of Band Releases-908481-2005/07/01-JeffJon
// Make sure we have a CurrentDrive set so that we can deal with
// UNC paths
if ( context . EngineSessionState . CurrentDrive = = null )
{
bool fsDriveSet = false ;
try
{
// Set the current drive to the first FileSystem drive if it exists.
ProviderInfo fsProvider = context . EngineSessionState . GetSingleProvider ( context . ProviderNames . FileSystem ) ;
Collection < PSDriveInfo > fsDrives = fsProvider . Drives ;
if ( fsDrives ! = null & & fsDrives . Count > 0 )
{
context . EngineSessionState . CurrentDrive = fsDrives [ 0 ] ;
fsDriveSet = true ;
}
}
catch ( ProviderNotFoundException )
{
}
if ( ! fsDriveSet )
{
Collection < PSDriveInfo > allDrives = context . EngineSessionState . Drives ( null ) ;
if ( allDrives ! = null & & allDrives . Count > 0 )
{
context . EngineSessionState . CurrentDrive = allDrives [ 0 ] ;
}
else
{
ItemNotFoundException itemNotFound =
new ItemNotFoundException ( Directory . GetCurrentDirectory ( ) , "PathNotFound" , SessionStateStrings . PathNotFound ) ;
context . ReportEngineStartupError ( itemNotFound ) ;
proceedWithSetLocation = false ;
}
}
}
if ( proceedWithSetLocation & & setLocation )
{
CmdletProviderContext providerContext = new CmdletProviderContext ( context ) ;
try
{
context . EngineSessionState . SetLocation ( Directory . GetCurrentDirectory ( ) , providerContext ) ;
}
catch ( ItemNotFoundException )
{
// If we can't access the Environment.CurrentDirectory, we may be in an AppContainer. Set the
// default drive to $pshome
System . Diagnostics . Process currentProcess = System . Diagnostics . Process . GetCurrentProcess ( ) ;
string defaultPath = System . IO . Path . GetDirectoryName ( PsUtils . GetMainModule ( currentProcess ) . FileName ) ;
context . EngineSessionState . SetLocation ( defaultPath , providerContext ) ;
}
}
}
}
catch ( Exception e ) // swallow all non-severe exceptions
{
CommandProcessorBase . CheckForSevereException ( e ) ;
}
}
internal static void CreateQuestionVariable ( ExecutionContext context )
{
QuestionMarkVariable qv = new QuestionMarkVariable ( context ) ;
context . EngineSessionState . SetVariableAtScope ( qv , "global" , true , CommandOrigin . Internal ) ;
}
/// <summary>
/// Remove anything that would have been bound by this ISS instance.
/// At this point, it removes assemblies and cmdlet entries at the top level.
/// It also removes types and formats.
/// The other entry types - functions, variables, aliases
/// are not removed by this function.
/// </summary>
/// <param name="context"></param>
internal void Unbind ( ExecutionContext context )
{
lock ( _syncObject )
{
SessionStateInternal ss = context . EngineSessionState ;
// Remove the assemblies from the assembly cache...
foreach ( SessionStateAssemblyEntry ssae in Assemblies )
{
context . RemoveAssembly ( ssae . Name ) ;
}
// Remove all of the commands from the top-level session state.
foreach ( SessionStateCommandEntry cmd in Commands )
{
SessionStateCmdletEntry ssce = cmd as SessionStateCmdletEntry ;
if ( ssce ! = null )
{
List < CmdletInfo > matches ;
if ( context . TopLevelSessionState . GetCmdletTable ( ) . TryGetValue ( ssce . Name , out matches ) )
{
// Remove the name from the list...
for ( int i = matches . Count - 1 ; i > = 0 ; i - - )
{
if ( matches [ i ] . ModuleName . Equals ( cmd . PSSnapIn . Name ) )
{
string name = matches [ i ] . Name ;
matches . RemoveAt ( i ) ;
context . TopLevelSessionState . RemoveCmdlet ( name , i , /*force*/ true ) ;
}
}
// And remove the entry if the list is now empty...
if ( matches . Count = = 0 )
{
context . TopLevelSessionState . RemoveCmdletEntry ( ssce . Name , true ) ;
}
}
continue ;
}
}
// Remove all of the providers from the top-level provider table.
if ( _providers ! = null & & _providers . Count > 0 )
{
Dictionary < string , List < ProviderInfo > > providerTable = context . TopLevelSessionState . Providers ;
foreach ( SessionStateProviderEntry sspe in _providers )
{
List < ProviderInfo > pl ;
if ( providerTable . TryGetValue ( sspe . Name , out pl ) )
{
Diagnostics . Assert ( pl ! = null , "There should never be a null list of entries in the provider table" ) ;
// For each provider with the same name...
for ( int i = pl . Count - 1 ; i > = 0 ; i - - )
{
ProviderInfo pi = pl [ i ] ;
// If it was implemented by this entry, remove it
if ( pi . ImplementingType = = sspe . ImplementingType )
{
RemoveAllDrivesForProvider ( pi , context . TopLevelSessionState ) ;
pl . RemoveAt ( i ) ;
}
}
// If there are no providers left with this name, remove the key.
if ( pl . Count = = 0 )
{
providerTable . Remove ( sspe . Name ) ;
}
}
}
}
List < string > formatFilesToRemove = new List < string > ( ) ;
if ( this . Formats ! = null )
{
formatFilesToRemove . AddRange ( this . Formats . Select ( f = > f . FileName ) ) ;
}
List < string > typeFilesToRemove = new List < string > ( ) ;
if ( this . Types ! = null )
{
typeFilesToRemove . AddRange ( this . Types . Select ( t = > t . FileName ) ) ;
}
RemoveTypesAndFormats ( context , formatFilesToRemove , typeFilesToRemove ) ;
}
}
internal static void RemoveTypesAndFormats ( ExecutionContext context , IList < string > formatFilesToRemove , IList < string > typeFilesToRemove )
{
// The formats and types tables are implemented in such a way that
// we can't simply remove an entry. We need to edit the list, clear the
// exiting composed table and then rebuild the entire table.
if ( formatFilesToRemove ! = null & & formatFilesToRemove . Count > 0 )
{
var newFormats = new InitialSessionStateEntryCollection < SessionStateFormatEntry > ( ) ;
HashSet < string > formatFilesToRemoveSet = new HashSet < string > ( formatFilesToRemove , StringComparer . OrdinalIgnoreCase ) ;
foreach ( SessionStateFormatEntry entry in context . InitialSessionState . Formats )
{
if ( ! formatFilesToRemoveSet . Contains ( entry . FileName ) )
{
newFormats . Add ( entry ) ;
}
}
context . InitialSessionState . Formats . Clear ( ) ;
context . InitialSessionState . Formats . Add ( newFormats ) ;
context . InitialSessionState . UpdateFormats ( context , false ) ;
}
if ( typeFilesToRemove ! = null & & typeFilesToRemove . Count > 0 )
{
// The types table has the same issue as the format table - we need to rebuild the entire table.
var newTypes = new InitialSessionStateEntryCollection < SessionStateTypeEntry > ( ) ;
List < string > resolvedTypeFilesToRemove = new List < string > ( ) ;
foreach ( var typeFile in typeFilesToRemove )
{
resolvedTypeFilesToRemove . Add ( ModuleCmdletBase . ResolveRootedFilePath ( typeFile , context ) ? ? typeFile ) ;
}
foreach ( SessionStateTypeEntry entry in context . InitialSessionState . Types )
{
if ( entry . FileName = = null )
{
// The entry is associated with a TypeData instance
newTypes . Add ( entry ) ;
}
else
{
// Resolving the file path because the path to the types file in module manifest is now specified as
// ..\..\types.ps1xml which expands to C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Core\..\..\types.ps1xml
string filePath = ModuleCmdletBase . ResolveRootedFilePath ( entry . FileName , context ) ? ? entry . FileName ;
if ( ! resolvedTypeFilesToRemove . Contains ( filePath ) )
{
newTypes . Add ( entry ) ;
}
}
}
// If there are any types that need to be added to the typetable, update them.
// Else, clear the typetable
if ( newTypes . Count > 0 )
{
context . InitialSessionState . Types . Clear ( ) ;
context . InitialSessionState . Types . Add ( newTypes ) ;
context . InitialSessionState . UpdateTypes ( context , false ) ;
}
else
{
context . TypeTable . Clear ( ) ;
}
}
}
/// <summary>
/// Update the type metadata loaded into this runspace
/// </summary>
/// <param name="context">The execution context for the runspace to update</param>
/// <param name="updateOnly">if true, re-initialize the metadata collection...</param>
internal void UpdateTypes ( ExecutionContext context , bool updateOnly )
{
if ( Types . Count = = 1 )
{
TypeTable typeTable = Types [ 0 ] . TypeTable ;
if ( typeTable ! = null )
{
// reuse the TypeTable instance specified in the sste.
// this essentially allows for TypeTable sharing across
// multiple runspaces.
context . TypeTable = typeTable ;
Types . Clear ( ) ;
Types . Add ( typeTable . typesInfo ) ;
return ;
}
}
if ( ! updateOnly )
{
context . TypeTable . Clear ( ) ;
}
ConcurrentBag < string > errors = new ConcurrentBag < string > ( ) ;
// Use at most 3 locks (we don't expect contention on that many cores anyways,
// and typically we'll be processing just 2 or 3 files anyway, hence capacity=3.
ConcurrentDictionary < string , string > filesProcessed
= new ConcurrentDictionary < string , string > ( /*concurrencyLevel*/ 3 , /*capacity*/ 3 , StringComparer . OrdinalIgnoreCase ) ;
Parallel . ForEach ( Types , sste = >
2016-07-29 22:02:49 +02:00
// foreach (var sste in Types)
2016-03-30 23:20:52 +02:00
{
if ( sste . FileName ! = null )
{
if ( filesProcessed . TryAdd ( sste . FileName , null ) )
{
string moduleName = "" ;
if ( sste . PSSnapIn ! = null & & ! String . IsNullOrEmpty ( sste . PSSnapIn . Name ) )
{
moduleName = sste . PSSnapIn . Name ;
}
bool unused ;
context . TypeTable . Update ( moduleName , sste . FileName , errors ,
context . AuthorizationManager , context . EngineHostInterface , out unused ) ;
}
}
else if ( sste . TypeTable ! = null )
{
// We get here only if it's NOT updating the existing type table
// because we cannot do the update with a type table instance
errors . Add ( TypesXmlStrings . TypeTableCannotCoExist ) ;
}
else
{
context . TypeTable . Update ( sste . TypeData , errors , sste . IsRemove ) ;
}
} ) ;
2016-07-29 22:02:49 +02:00
// }
2016-03-30 23:20:52 +02:00
context . TypeTable . ClearConsolidatedMembers ( ) ;
if ( updateOnly )
{
// Put the SessionStateTypeEntry into the cache if we are updating the type table
foreach ( var sste in Types )
{
context . InitialSessionState . Types . Add ( sste ) ;
}
}
if ( errors . Count > 0 )
{
var allErrors = new StringBuilder ( '\n' ) ;
foreach ( string error in errors )
{
if ( ! string . IsNullOrEmpty ( error ) )
{
if ( this . ThrowOnRunspaceOpenError | | this . RefreshTypeAndFormatSetting )
{
allErrors . Append ( error ) ;
allErrors . Append ( '\n' ) ;
}
else
{
context . ReportEngineStartupError ( ExtendedTypeSystem . TypesXmlError , error ) ;
}
}
}
if ( this . ThrowOnRunspaceOpenError )
{
string resource = ExtendedTypeSystem . TypesXmlError ;
ThrowTypeOrFormatErrors ( resource , allErrors . ToString ( ) , "ErrorsUpdatingTypes" ) ;
}
if ( this . RefreshTypeAndFormatSetting )
{
string resource = ExtendedTypeSystem . TypesXmlError ;
ThrowTypeOrFormatErrors ( resource , allErrors . ToString ( ) , "ErrorsUpdatingTypes" ) ;
}
}
}
/// <summary>
/// Update the formatting information for a runspace
/// </summary>
/// <param name="context">The execution context for the runspace to be updated</param>
/// <param name="update">True if we only want to add stuff, false if we want to reinitialize</param>
internal void UpdateFormats ( ExecutionContext context , bool update )
{
if ( DisableFormatUpdates | | this . Formats . Count = = 0 )
{
return ;
}
Collection < PSSnapInTypeAndFormatErrors > entries = new Collection < PSSnapInTypeAndFormatErrors > ( ) ;
InitialSessionStateEntryCollection < SessionStateFormatEntry > formatsToLoad ;
// If we're just updating the current runspace, then we'll add our entries
// to the current list otherwise, we'll build a new list...
if ( update & & context . InitialSessionState ! = null )
{
formatsToLoad = context . InitialSessionState . Formats ;
formatsToLoad . Add ( this . Formats ) ;
}
else
{
formatsToLoad = this . Formats ;
}
HashSet < string > filesProcessed = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
foreach ( SessionStateFormatEntry ssfe in formatsToLoad )
{
string name = ssfe . FileName ;
PSSnapInInfo snapin = ssfe . PSSnapIn ;
if ( snapin ! = null & & ! string . IsNullOrEmpty ( snapin . Name ) )
{
name = snapin . Name ;
}
if ( ssfe . Formattable ! = null )
{
if ( formatsToLoad . Count = = 1 )
{
context . FormatDBManager = ssfe . Formattable . FormatDBManager ;
}
else
{
// if a SharedFormatTable is allowed then only one
// entry can be specified.
throw PSTraceSource . NewInvalidOperationException ( FormatAndOutXmlLoadingStrings . FormatTableCannotCoExist ) ;
}
}
2016-07-29 22:02:49 +02:00
else if ( ssfe . FormatData ! = null )
2016-03-30 23:20:52 +02:00
{
entries . Add ( new PSSnapInTypeAndFormatErrors ( name , ssfe . FormatData ) ) ;
}
else
{
if ( ! filesProcessed . Contains ( ssfe . FileName ) )
{
filesProcessed . Add ( ssfe . FileName ) ;
entries . Add ( new PSSnapInTypeAndFormatErrors ( name , ssfe . FileName ) ) ;
}
}
}
if ( entries . Count > 0 )
{
context . FormatDBManager . UpdateDataBase ( entries , context . AuthorizationManager , context . EngineHostInterface , true ) ;
var allErrors = new StringBuilder ( "\n" ) ;
bool hasErrors = false ;
// Now see if there were any errors in the format files and report them
// if this is the case...
foreach ( PSSnapInTypeAndFormatErrors entry in entries )
{
if ( entry . Errors ! = null & & entry . Errors . Count > 0 )
{
foreach ( string error in entry . Errors )
{
if ( ! string . IsNullOrEmpty ( error ) )
{
hasErrors = true ;
if ( this . ThrowOnRunspaceOpenError | | this . RefreshTypeAndFormatSetting )
{
allErrors . Append ( error ) ;
allErrors . Append ( '\n' ) ;
}
else
{
context . ReportEngineStartupError ( FormatAndOutXmlLoadingStrings . FormatLoadingErrors , error ) ;
}
}
}
}
}
if ( ( this . ThrowOnRunspaceOpenError | | this . RefreshTypeAndFormatSetting ) & & hasErrors )
{
string resource = FormatAndOutXmlLoadingStrings . FormatLoadingErrors ;
ThrowTypeOrFormatErrors ( resource , allErrors . ToString ( ) , "ErrorsUpdatingFormats" ) ;
}
}
}
private static void ThrowTypeOrFormatErrors ( string resourceString , string errorMsg , string errorId )
{
string message = StringUtil . Format ( resourceString , errorMsg ) ;
var ex = new RuntimeException ( message ) ;
ex . SetErrorId ( errorId ) ;
throw ex ;
}
/// <summary>
/// Need to have SnapIn support till we move to modules
/// </summary>
/// <param name="name"></param>
/// <param name="warning"></param>
/// <returns></returns>
public PSSnapInInfo ImportPSSnapIn ( string name , out PSSnapInException warning )
{
if ( string . IsNullOrEmpty ( name ) )
{
PSTraceSource . NewArgumentNullException ( "name" ) ;
}
// Check whether the mshsnapin is present in the registry.
// TODO: Note the hard-coded version number here, this was part of the SingleShell
// implementation and should be refactored.
PSSnapInInfo newPSSnapIn = PSSnapInReader . Read ( "2" , name ) ;
if ( ! Utils . IsPSVersionSupported ( newPSSnapIn . PSVersion . ToString ( ) ) )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "MshSnapin {0} and current monad engine's versions don't match." , name ) ;
2016-03-30 23:20:52 +02:00
throw PSTraceSource . NewArgumentException ( "mshSnapInID" ,
ConsoleInfoErrorStrings . AddPSSnapInBadMonadVersion ,
newPSSnapIn . PSVersion . ToString ( ) ,
"2.0" ) ;
}
// Now actually load the snapin...
PSSnapInInfo snapin = ImportPSSnapIn ( newPSSnapIn , out warning ) ;
if ( null ! = snapin )
{
2016-08-02 22:29:09 +02:00
ImportedSnapins . Add ( snapin . Name , snapin ) ;
2016-03-30 23:20:52 +02:00
}
return snapin ;
}
internal PSSnapInInfo ImportCorePSSnapIn ( )
{
// Load Microsoft.PowerShell.Core as a snapin
PSSnapInInfo coreSnapin = PSSnapInReader . ReadCoreEngineSnapIn ( ) ;
this . defaultSnapins . Add ( coreSnapin ) ;
try
{
PSSnapInException warning ;
this . ImportPSSnapIn ( coreSnapin , out warning ) ;
}
catch ( PSSnapInException pse )
{
throw pse ;
}
return coreSnapin ;
}
2016-04-06 21:01:07 +02:00
// WARNING: THIS CODE IS COMPLETELY DUPLICATED IN RunspaceConfigForSingleShell
2016-03-30 23:20:52 +02:00
internal PSSnapInInfo ImportPSSnapIn ( PSSnapInInfo psSnapInInfo , out PSSnapInException warning )
{
// See if the snapin is already loaded. If has been then there will be an entry in the
// Assemblies list for it already...
bool reload = true ;
foreach ( SessionStateAssemblyEntry ae in this . Assemblies )
{
PSSnapInInfo loadedPSSnapInInfo = ae . PSSnapIn ;
if ( loadedPSSnapInInfo ! = null )
{
// See if the assembly-qualified names match and return the existing PSSnapInInfo
// if they do.
string loadedSnapInName = ae . PSSnapIn . AssemblyName ;
if ( ! string . IsNullOrEmpty ( loadedSnapInName )
& & string . Equals ( loadedSnapInName , psSnapInInfo . AssemblyName , System . StringComparison . OrdinalIgnoreCase ) )
{
warning = null ;
// the previous implementation used to return the
// same loaded snap-in value. This results in the
// commands/types/formats exposed in the snap-in
// to be not populated in the InitialSessionState
// object. This is being fixed
reload = false ;
break ;
}
}
}
Dictionary < string , SessionStateCmdletEntry > cmdlets = null ;
Dictionary < string , List < SessionStateAliasEntry > > aliases = null ;
Dictionary < string , SessionStateProviderEntry > providers = null ;
if ( psSnapInInfo = = null )
{
ArgumentNullException e = new ArgumentNullException ( "psSnapInInfo" ) ;
throw e ;
}
#if ! CORECLR // CustomPSSnapIn Not Supported On CSS.
if ( ! String . IsNullOrEmpty ( psSnapInInfo . CustomPSSnapInType ) )
{
LoadCustomPSSnapIn ( psSnapInInfo ) ;
warning = null ;
return psSnapInInfo ;
}
#endif
Assembly assembly = null ;
string helpFile = null ;
if ( reload )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly for psSnapIn {0}" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
assembly = PSSnapInHelpers . LoadPSSnapInAssembly ( psSnapInInfo , out cmdlets , out providers ) ;
if ( assembly = = null )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "Loading assembly for psSnapIn {0} failed" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
warning = null ;
return null ; //BUGBUG - should add something to the warnings list here instead of quitting...
}
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly for psSnapIn {0} succeeded" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
PSSnapInHelpers . AnalyzePSSnapInAssembly ( assembly , psSnapInInfo . Name , psSnapInInfo , null , true , out cmdlets , out aliases , out providers , out helpFile ) ;
}
// We skip checking if the file exists when it's in $PSHOME because of magic
// where we have the former contents of those files built into the engine directly.
var psHome = Utils . GetApplicationBase ( Utils . DefaultPowerShellShellID ) ;
foreach ( string file in psSnapInInfo . Types )
{
string path = Path . Combine ( psSnapInInfo . ApplicationBase , file ) ;
if ( ! string . Equals ( psHome , psSnapInInfo . ApplicationBase , StringComparison . OrdinalIgnoreCase )
& & ! File . Exists ( path ) )
{
// Remove the application base directory if assembly doesn't exist in it.
path = file ;
}
SessionStateTypeEntry typeEntry = new SessionStateTypeEntry ( path ) ;
typeEntry . SetPSSnapIn ( psSnapInInfo ) ;
this . Types . Add ( typeEntry ) ;
}
foreach ( string file in psSnapInInfo . Formats )
{
string path = Path . Combine ( psSnapInInfo . ApplicationBase , file ) ;
if ( ! string . Equals ( psHome , psSnapInInfo . ApplicationBase , StringComparison . OrdinalIgnoreCase )
& & ! File . Exists ( path ) )
{
path = file ;
}
SessionStateFormatEntry formatEntry = new SessionStateFormatEntry ( path ) ;
formatEntry . SetPSSnapIn ( psSnapInInfo ) ;
this . Formats . Add ( formatEntry ) ;
}
SessionStateAssemblyEntry assemblyEntry =
new SessionStateAssemblyEntry ( psSnapInInfo . AssemblyName , psSnapInInfo . AbsoluteModulePath ) ;
assemblyEntry . SetPSSnapIn ( psSnapInInfo ) ;
this . Assemblies . Add ( assemblyEntry ) ;
// entry from types.ps1xml references a type (Microsoft.PowerShell.Commands.SecurityDescriptorCommandsBase) in this assembly
if ( psSnapInInfo . Name . Equals ( CoreSnapin , StringComparison . OrdinalIgnoreCase ) )
{
assemblyEntry = new SessionStateAssemblyEntry ( "Microsoft.PowerShell.Security" , null ) ;
this . Assemblies . Add ( assemblyEntry ) ;
}
if ( cmdlets ! = null )
{
foreach ( SessionStateCmdletEntry cmdlet in cmdlets . Values )
{
SessionStateCmdletEntry newEntry = ( SessionStateCmdletEntry ) cmdlet . Clone ( ) ;
newEntry . Visibility = this . DefaultCommandVisibility ;
this . Commands . Add ( newEntry ) ;
}
}
if ( aliases ! = null )
{
foreach ( var cmdletAliasesEntry in aliases . Values )
{
foreach ( var sessionStateAliasEntry in cmdletAliasesEntry )
{
sessionStateAliasEntry . Visibility = this . DefaultCommandVisibility ;
this . Commands . Add ( sessionStateAliasEntry ) ;
}
}
}
if ( providers ! = null )
{
foreach ( SessionStateProviderEntry provider in providers . Values )
{
this . Providers . Add ( provider ) ;
}
}
warning = null ;
// Add help file information for built-in functions
if ( psSnapInInfo . Name . Equals ( CoreSnapin , StringComparison . OrdinalIgnoreCase ) )
{
foreach ( var f in BuiltInFunctions )
{
Collection < SessionStateCommandEntry > funcList = Commands [ f . Name ] ;
foreach ( var func in funcList )
{
if ( func is SessionStateFunctionEntry )
{
2016-07-29 22:02:49 +02:00
( ( SessionStateFunctionEntry ) func ) . SetHelpFile ( helpFile ) ;
2016-03-30 23:20:52 +02:00
}
}
}
}
return psSnapInInfo ;
}
internal List < PSSnapInInfo > GetPSSnapIn ( string psSnapinName )
{
List < PSSnapInInfo > loadedSnapins = null ;
foreach ( var defaultSnapin in defaultSnapins )
{
if ( defaultSnapin . Name . Equals ( psSnapinName , StringComparison . OrdinalIgnoreCase ) )
{
if ( loadedSnapins = = null )
{
loadedSnapins = new List < PSSnapInInfo > ( ) ;
}
loadedSnapins . Add ( defaultSnapin ) ;
}
}
PSSnapInInfo importedSnapin = null ;
2016-08-02 22:29:09 +02:00
if ( ImportedSnapins . TryGetValue ( psSnapinName , out importedSnapin ) )
2016-03-30 23:20:52 +02:00
{
if ( loadedSnapins = = null )
{
loadedSnapins = new List < PSSnapInInfo > ( ) ;
}
loadedSnapins . Add ( importedSnapin ) ;
}
return loadedSnapins ;
}
#if ! CORECLR // CustomPSSnapIn Not Supported On CSS.
/// <summary>
/// This is a "proxy" snapin that loads a subset of cmdlets from another snapin...
/// </summary>
/// <remarks>
/// CustomPSSnapIn derives from System.Configuration.Install, which is not in CoreCLR.
/// So CustomPSSnapIn is not supported on CSS.
/// </remarks>
/// <param name="psSnapInInfo">The snapin to examine.</param>
private void LoadCustomPSSnapIn ( PSSnapInInfo psSnapInInfo )
{
if ( psSnapInInfo = = null )
return ;
if ( String . IsNullOrEmpty ( psSnapInInfo . CustomPSSnapInType ) )
{
return ;
}
Dictionary < string , SessionStateCmdletEntry > cmdlets = null ;
Dictionary < string , SessionStateProviderEntry > providers = null ;
Assembly assembly = null ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly for mshsnapin {0}" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
assembly = PSSnapInHelpers . LoadPSSnapInAssembly ( psSnapInInfo , out cmdlets , out providers ) ;
if ( assembly = = null )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "Loading assembly for mshsnapin {0} failed" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
return ;
}
CustomPSSnapIn customPSSnapIn = null ;
try
{
Type type = assembly . GetType ( psSnapInInfo . CustomPSSnapInType , true ) ;
if ( type ! = null )
{
customPSSnapIn = ( CustomPSSnapIn ) assembly . CreateInstance ( psSnapInInfo . CustomPSSnapInType ) ;
}
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly for mshsnapin {0} succeeded" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
}
catch ( TypeLoadException tle )
{
throw new PSSnapInException ( psSnapInInfo . Name , tle . Message ) ;
}
catch ( ArgumentException ae )
{
throw new PSSnapInException ( psSnapInInfo . Name , ae . Message ) ;
}
catch ( MissingMethodException mme )
{
throw new PSSnapInException ( psSnapInInfo . Name , mme . Message ) ;
}
catch ( InvalidCastException ice )
{
throw new PSSnapInException ( psSnapInInfo . Name , ice . Message ) ;
}
catch ( TargetInvocationException tie )
{
if ( tie . InnerException ! = null )
{
throw new PSSnapInException ( psSnapInInfo . Name , tie . InnerException . Message ) ;
}
throw new PSSnapInException ( psSnapInInfo . Name , tie . Message ) ;
}
MergeCustomPSSnapIn ( psSnapInInfo , customPSSnapIn ) ;
}
private void MergeCustomPSSnapIn ( PSSnapInInfo psSnapInInfo , CustomPSSnapIn customPSSnapIn )
{
if ( psSnapInInfo = = null | | customPSSnapIn = = null )
return ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Merging configuration from custom mshsnapin {0}" , psSnapInInfo . Name ) ;
2016-03-30 23:20:52 +02:00
if ( customPSSnapIn . Cmdlets ! = null )
{
foreach ( CmdletConfigurationEntry entry in customPSSnapIn . Cmdlets )
{
SessionStateCmdletEntry cmdlet = new SessionStateCmdletEntry ( entry . Name , entry . ImplementingType , entry . HelpFileName ) ;
cmdlet . SetPSSnapIn ( psSnapInInfo ) ;
this . Commands . Add ( cmdlet ) ;
}
}
if ( customPSSnapIn . Providers ! = null )
{
foreach ( ProviderConfigurationEntry entry in customPSSnapIn . Providers )
{
SessionStateProviderEntry provider = new SessionStateProviderEntry ( entry . Name , entry . ImplementingType , entry . HelpFileName ) ;
provider . SetPSSnapIn ( psSnapInInfo ) ;
this . Providers . Add ( provider ) ;
}
}
if ( customPSSnapIn . Types ! = null )
{
foreach ( TypeConfigurationEntry entry in customPSSnapIn . Types )
{
string path = Path . Combine ( psSnapInInfo . ApplicationBase , entry . FileName ) ;
SessionStateTypeEntry typeEntry = new SessionStateTypeEntry ( path ) ;
typeEntry . SetPSSnapIn ( psSnapInInfo ) ;
this . Types . Add ( typeEntry ) ;
}
}
if ( customPSSnapIn . Formats ! = null )
{
foreach ( FormatConfigurationEntry entry in customPSSnapIn . Formats )
{
string path = Path . Combine ( psSnapInInfo . ApplicationBase , entry . FileName ) ;
SessionStateFormatEntry formatEntry = new SessionStateFormatEntry ( path ) ;
formatEntry . SetPSSnapIn ( psSnapInInfo ) ;
this . Formats . Add ( formatEntry ) ;
}
}
SessionStateAssemblyEntry assemblyEntry = new SessionStateAssemblyEntry ( psSnapInInfo . AssemblyName , psSnapInInfo . AbsoluteModulePath ) ;
this . Assemblies . Add ( assemblyEntry ) ;
}
#endif
[SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom")]
internal static Assembly LoadAssemblyFromFile ( string fileName )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly for psSnapIn {0}" , fileName ) ;
2016-03-30 23:20:52 +02:00
Assembly assembly = ClrFacade . LoadFrom ( fileName ) ;
if ( assembly = = null )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "Loading assembly for psSnapIn {0} failed" , fileName ) ;
2016-03-30 23:20:52 +02:00
return null ;
}
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly for psSnapIn {0} succeeded" , fileName ) ;
2016-03-30 23:20:52 +02:00
return assembly ;
}
internal void ImportCmdletsFromAssembly ( Assembly assembly , PSModuleInfo module )
{
if ( assembly = = null )
{
ArgumentNullException e = new ArgumentNullException ( "assembly" ) ;
throw e ;
}
Dictionary < string , SessionStateCmdletEntry > cmdlets = null ;
Dictionary < string , List < SessionStateAliasEntry > > aliases = null ;
Dictionary < string , SessionStateProviderEntry > providers = null ;
2016-04-28 22:41:25 +02:00
string assemblyPath = assembly . Location ;
2016-03-30 23:20:52 +02:00
string throwAwayHelpFile = null ;
PSSnapInHelpers . AnalyzePSSnapInAssembly ( assembly , assemblyPath , null , module , true , out cmdlets , out aliases , out providers , out throwAwayHelpFile ) ;
SessionStateAssemblyEntry assemblyEntry =
new SessionStateAssemblyEntry ( assembly . FullName , assemblyPath ) ;
this . Assemblies . Add ( assemblyEntry ) ;
if ( cmdlets ! = null )
{
foreach ( SessionStateCmdletEntry cmdlet in cmdlets . Values )
{
this . Commands . Add ( cmdlet ) ;
}
}
if ( aliases ! = null )
{
foreach ( var cmdletAliasesEntry in aliases . Values )
{
foreach ( var sessionStateAliasEntry in cmdletAliasesEntry )
{
this . Commands . Add ( sessionStateAliasEntry ) ;
}
}
}
if ( providers ! = null )
{
foreach ( SessionStateProviderEntry provider in providers . Values )
{
this . Providers . Add ( provider ) ;
}
}
}
//
// Now define a bunch of functions that describe the rest of the default session state...
//
internal const string FormatEnumerationLimit = "FormatEnumerationLimit" ;
internal const int DefaultFormatEnumerationLimit = 4 ;
/// <summary>
/// This is the default function to use for tab expansion.
/// </summary>
2016-07-29 22:02:49 +02:00
private static string s_tabExpansionFunctionText = @ "
2016-03-30 23:20:52 +02:00
< # Options include :
RelativeFilePaths - [ bool ]
Always resolve file paths using Resolve - Path - Relative .
The default is to use some heuristics to guess if relative or absolute is better .
To customize your own custom options , pass a hashtable to CompleteInput , e . g .
return [ System . Management . Automation . CommandCompletion ] : : CompleteInput ( $ inputScript , $ cursorColumn ,
@ { RelativeFilePaths = $ false }
# >
[CmdletBinding(DefaultParameterSetName = 'ScriptInputSet')]
Param (
[Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 0)]
[string] $ inputScript ,
[Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 1)]
[int] $ cursorColumn ,
[Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 0)]
[System.Management.Automation.Language.Ast] $ ast ,
[Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 1)]
[System.Management.Automation.Language.Token[] ] $ tokens ,
[Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 2)]
[System.Management.Automation.Language.IScriptPosition] $ positionOfCursor ,
[Parameter(ParameterSetName = 'ScriptInputSet', Position = 2)]
[Parameter(ParameterSetName = 'AstInputSet', Position = 3)]
[Hashtable] $ options = $ null
)
End
{
if ( $ psCmdlet . ParameterSetName - eq ' ScriptInputSet ' )
{
return [ System . Management . Automation . CommandCompletion ] : : CompleteInput (
< # inputScript # > $ inputScript ,
< # cursorColumn # > $ cursorColumn ,
< # options # > $ options )
}
else
{
return [ System . Management . Automation . CommandCompletion ] : : CompleteInput (
< # ast # > $ ast ,
< # tokens # > $ tokens ,
< # positionOfCursor # > $ positionOfCursor ,
< # options # > $ options )
}
}
";
/// <summary>
/// This is the default function to use for 'Import System Modules'.
/// </summary>
/// <remarks>
/// Win8: 320909. Retaining the original definition to ensure backward compatability.
/// </remarks>
2016-07-29 22:02:49 +02:00
private static string s_importSystemModulesText = @"" ;
2016-03-30 23:20:52 +02:00
2016-04-06 21:01:07 +02:00
/// <summary>
/// This is the default function to use for clear-host. On Windows it rewrites the
/// host, and on Linux, it delegates to the native binary, 'clear'.
/// </summary>
internal static string GetClearHostFunctionText ( )
{
2016-04-08 23:54:41 +02:00
if ( Platform . IsWindows )
2016-04-06 21:01:07 +02:00
{
return @ "
$ RawUI = $ Host . UI . RawUI
$ RawUI . CursorPosition = @ { X = 0 ; Y = 0 }
$ RawUI . SetBufferContents (
@ { Top = - 1 ; Bottom = - 1 ; Right = - 1 ; Left = - 1 } ,
@ { Character = ' ' ; ForegroundColor = $ rawui . ForegroundColor ; BackgroundColor = $ rawui . BackgroundColor } )
# . Link
# http : //go.microsoft.com/fwlink/?LinkID=225747
# . ExternalHelp System . Management . Automation . dll - help . xml
";
}
else
{
// Porting note: non-Windows platforms use `clear`
2016-07-06 01:02:06 +02:00
return "& (Get-Command -CommandType Application clear | Select-Object -First 1).Definition" ;
2016-04-06 21:01:07 +02:00
}
}
2016-03-30 23:20:52 +02:00
/// <summary>
/// This is the default function to use for man/help. It uses
/// splatting to pass in the parameters.
/// </summary>
internal static string GetHelpPagingFunctionText ( )
{
// We used to generate the text for this function so you could add a parameter
// to Get-Help and not worry about adding it here. That was a little slow at
// startup, so it's hard coded, with a test to make sure the parameters match.
return @ "
< #
. FORWARDHELPTARGETNAME Get - Help
. FORWARDHELPCATEGORY Cmdlet
# >
[CmdletBinding(DefaultParameterSetName='AllUsersView', HelpUri='http://go.microsoft.com/fwlink/?LinkID=113316')]
param (
[Parameter(Position=0, ValueFromPipelineByPropertyName=$true)]
[string]
$ { Name } ,
[string]
$ { Path } ,
[ValidateSet('Alias','Cmdlet','Provider','General','FAQ','Glossary','HelpFile','ScriptCommand','Function','Filter','ExternalScript','All','DefaultHelp','Workflow','DscResource','Class','Configuration')]
[string[] ]
$ { Category } ,
[string[] ]
$ { Component } ,
[string[] ]
$ { Functionality } ,
[string[] ]
$ { Role } ,
[Parameter(ParameterSetName='DetailedView', Mandatory=$true)]
[switch]
$ { Detailed } ,
[Parameter(ParameterSetName='AllUsersView')]
[switch]
$ { Full } ,
[Parameter(ParameterSetName='Examples', Mandatory=$true)]
[switch]
$ { Examples } ,
[Parameter(ParameterSetName='Parameters', Mandatory=$true)]
[string]
$ { Parameter } ,
[Parameter(ParameterSetName='Online', Mandatory=$true)]
[switch]
$ { Online } ,
[Parameter(ParameterSetName='ShowWindow', Mandatory=$true)]
[switch]
$ { ShowWindow } )
# Set the outputencoding to Console : : OutputEncoding . More . com doesn ' t work well with Unicode .
$ outputEncoding = [ System . Console ] : : OutputEncoding
Get - Help @PSBoundParameters | more
";
}
internal static string GetMkdirFunctionText ( )
{
return @ "
< #
. FORWARDHELPTARGETNAME New - Item
. FORWARDHELPCATEGORY Cmdlet
# >
[ CmdletBinding ( DefaultParameterSetName = ' pathSet ' ,
SupportsShouldProcess = $ true ,
SupportsTransactions = $ true ,
ConfirmImpact = ' Medium ' ) ]
[OutputType([System.IO.DirectoryInfo] ) ]
param (
[Parameter(ParameterSetName='nameSet', Position=0, ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName='pathSet', Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[System.String[] ]
$ { Path } ,
[Parameter(ParameterSetName='nameSet', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[AllowNull()]
[AllowEmptyString()]
[System.String]
$ { Name } ,
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[System.Object]
$ { Value } ,
[Switch]
$ { Force } ,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[System.Management.Automation.PSCredential]
$ { Credential }
)
begin {
try {
$ wrappedCmd = $ ExecutionContext . InvokeCommand . GetCommand ( ' New - Item ' , [ System . Management . Automation . CommandTypes ] : : Cmdlet )
$ scriptCmd = { & $ wrappedCmd - Type Directory @PSBoundParameters }
$ steppablePipeline = $ scriptCmd . GetSteppablePipeline ( )
$ steppablePipeline . Begin ( $ PSCmdlet )
} catch {
throw
}
}
process {
try {
$ steppablePipeline . Process ( $ _ )
} catch {
throw
}
}
end {
try {
$ steppablePipeline . End ( )
} catch {
throw
}
}
";
}
internal static string GetGetVerbText ( )
{
return @ "
param (
[Parameter(ValueFromPipeline=$true)]
[string[] ]
$ verb = '*'
)
begin {
$ allVerbs = [ System . Reflection . IntrospectionExtensions ] : : GetTypeInfo ( [ PSObject ] ) . Assembly . ExportedTypes |
Microsoft . PowerShell . Core \ Where - Object { $ _ . Name - match ' ^ Verbs . ' } |
Microsoft . PowerShell . Utility \ Get - Member - type Properties - static |
Microsoft . PowerShell . Utility \ Select - Object @ {
Name = ' Verb '
Expression = { $ _ . Name }
} , @ {
Name = ' Group '
Expression = {
$ str = "" $ ( $ _ . TypeName ) ""
$ str . Substring ( $ str . LastIndexOf ( ' Verbs ' ) + 5 )
}
}
}
process {
foreach ( $ v in $ verb ) {
$ allVerbs | Microsoft . PowerShell . Core \ Where - Object { $ _ . Verb - like $ v }
}
}
# . Link
# http : //go.microsoft.com/fwlink/?LinkID=160712
# . ExternalHelp System . Management . Automation . dll - help . xml
";
}
internal static string GetOSTFunctionText ( )
{
return @ "
[CmdletBinding()]
param (
[ValidateRange(2, 2147483647)]
[int]
$ { Width } ,
[Parameter(ValueFromPipeline=$true)]
[psobject]
$ { InputObject } )
begin
{
try {
$ PSBoundParameters [ ' Stream ' ] = $ true
$ wrappedCmd = $ ExecutionContext . InvokeCommand . GetCommand ( ' Out - String ' , [ System . Management . Automation . CommandTypes ] : : Cmdlet )
$ scriptCmd = { & $ wrappedCmd @PSBoundParameters }
$ steppablePipeline = $ scriptCmd . GetSteppablePipeline ( $ myInvocation . CommandOrigin )
$ steppablePipeline . Begin ( $ PSCmdlet )
} catch {
throw
}
}
process
{
try {
$ steppablePipeline . Process ( $ _ )
} catch {
throw
}
}
end
{
try {
$ steppablePipeline . End ( )
} catch {
throw
}
}
< #
. ForwardHelpTargetName Out - String
. ForwardHelpCategory Cmdlet
# >
";
}
internal const ActionPreference defaultDebugPreference = ActionPreference . SilentlyContinue ;
internal const ActionPreference defaultErrorActionPreference = ActionPreference . Continue ;
internal const ActionPreference defaultProgressPreference = ActionPreference . Continue ;
internal const ActionPreference defaultVerbosePreference = ActionPreference . SilentlyContinue ;
internal const ActionPreference defaultWarningPreference = ActionPreference . Continue ;
internal const ActionPreference defaultInformationPreference = ActionPreference . SilentlyContinue ;
internal const bool defaultWhatIfPreference = false ;
internal const ConfirmImpact defaultConfirmPreference = ConfirmImpact . High ;
internal static SessionStateVariableEntry [ ] BuiltInVariables = new SessionStateVariableEntry [ ]
{
// Engine variables that should be precreated before running profile
// Bug fix for Win7:2202228 Engine halts if initial command fulls up variable table
// Anytime a new variable that the engine depends on to run is added, this table
// must be updated...
new SessionStateVariableEntry ( SpecialVariables . LastToken , null , String . Empty ) ,
new SessionStateVariableEntry ( SpecialVariables . FirstToken , null , String . Empty ) ,
new SessionStateVariableEntry ( SpecialVariables . StackTrace , null , String . Empty ) ,
// Variable which controls the encoding for piping data to a NativeCommand
new SessionStateVariableEntry (
SpecialVariables . OutputEncoding ,
System . Text . Encoding . ASCII ,
RunspaceInit . OutputEncodingDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( System . Text . Encoding ) )
) ,
// Preferences
// NTRAID#Windows Out Of Band Releases-931461-2006/03/13
// ArgumentTypeConverterAttribute is applied to these variables,
// but this only reaches the global variable. If these are
// redefined in script scope etc, the type conversion
// is not applicable.
// Variables typed to ActionPreference
new SessionStateVariableEntry (
SpecialVariables . ConfirmPreference ,
defaultConfirmPreference ,
RunspaceInit . ConfirmPreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ConfirmImpact ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . DebugPreference ,
defaultDebugPreference ,
RunspaceInit . DebugPreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ActionPreference ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . ErrorActionPreference ,
defaultErrorActionPreference ,
RunspaceInit . ErrorActionPreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ActionPreference ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . ProgressPreference ,
defaultProgressPreference ,
RunspaceInit . ProgressPreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ActionPreference ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . VerbosePreference ,
defaultVerbosePreference ,
RunspaceInit . VerbosePreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ActionPreference ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . WarningPreference ,
defaultWarningPreference ,
RunspaceInit . WarningPreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ActionPreference ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . InformationPreference ,
defaultInformationPreference ,
RunspaceInit . InformationPreferenceDescription ,
ScopedItemOptions . None ,
new ArgumentTypeConverterAttribute ( typeof ( ActionPreference ) )
) ,
new SessionStateVariableEntry (
SpecialVariables . ErrorView ,
"NormalView" ,
RunspaceInit . ErrorViewDescription
) ,
new SessionStateVariableEntry (
SpecialVariables . NestedPromptLevel ,
0 ,
RunspaceInit . NestedPromptLevelDescription
) ,
new SessionStateVariableEntry (
SpecialVariables . WhatIfPreference ,
defaultWhatIfPreference ,
RunspaceInit . WhatIfPreferenceDescription
) ,
new SessionStateVariableEntry (
FormatEnumerationLimit ,
DefaultFormatEnumerationLimit ,
RunspaceInit . FormatEnunmerationLimitDescription
) ,
//variable for PSEmailServer
new SessionStateVariableEntry (
SpecialVariables . PSEmailServer ,
String . Empty ,
RunspaceInit . PSEmailServerDescription
) ,
// Start: Variables which control remoting behavior
new SessionStateVariableEntry (
Microsoft . PowerShell . Commands . PSRemotingBaseCmdlet . DEFAULT_SESSION_OPTION ,
new System . Management . Automation . Remoting . PSSessionOption ( ) ,
RemotingErrorIdStrings . PSDefaultSessionOptionDescription ,
ScopedItemOptions . None ) ,
new SessionStateVariableEntry (
SpecialVariables . PSSessionConfigurationName ,
"http://schemas.microsoft.com/powershell/Microsoft.PowerShell" ,
RemotingErrorIdStrings . PSSessionConfigurationName ,
ScopedItemOptions . None ) ,
new SessionStateVariableEntry (
SpecialVariables . PSSessionApplicationName ,
"wsman" ,
RemotingErrorIdStrings . PSSessionAppName ,
ScopedItemOptions . None ) ,
// End: Variables which control remoting behavior
2016-04-09 00:04:27 +02:00
#region Platform
new SessionStateVariableEntry (
SpecialVariables . IsLinux ,
Platform . IsLinux ,
String . Empty ,
ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateVariableEntry (
SpecialVariables . IsOSX ,
Platform . IsOSX ,
String . Empty ,
ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateVariableEntry (
SpecialVariables . IsWindows ,
Platform . IsWindows ,
String . Empty ,
ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateVariableEntry (
2016-07-22 01:52:22 +02:00
SpecialVariables . IsCoreCLR ,
Platform . IsCoreCLR ,
2016-04-09 00:04:27 +02:00
String . Empty ,
ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
#endregion
2016-03-30 23:20:52 +02:00
} ;
/// <summary>
/// Returns a new array of alias entries everytime it's called. This
/// can't be static because the elements may be mutated in different session
/// state objects so each session state must have a copy of the entry.
/// </summary>
internal static SessionStateAliasEntry [ ] BuiltInAliases
{
get
{
return new SessionStateAliasEntry [ ] {
new SessionStateAliasEntry ( "foreach" ,
"ForEach-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "%" ,
"ForEach-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "where" ,
"Where-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "?" ,
"Where-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "clc" ,
"Clear-Content" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "cli" ,
"Clear-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "clp" ,
"Clear-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "clv" ,
"Clear-Variable" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "cpi" ,
"Copy-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "cvpa" ,
"Convert-Path" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "dbp" ,
"Disable-PSBreakpoint" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ebp" ,
"Enable-PSBreakpoint" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "epal" ,
"Export-Alias" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "epcsv" ,
"Export-Csv" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "fl" ,
"Format-List" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ft" ,
"Format-Table" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "fw" ,
"Format-Wide" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gal" ,
"Get-Alias" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gbp" ,
"Get-PSBreakpoint" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gc" ,
"Get-Content" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gci" ,
"Get-ChildItem" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gcm" ,
"Get-Command" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gdr" ,
"Get-PSDrive" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gcs" ,
"Get-PSCallStack" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ghy" ,
"Get-History" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gi" ,
"Get-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gl" ,
"Get-Location" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gm" ,
"Get-Member" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gmo" ,
"Get-Module" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gp" ,
"Get-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gpv" ,
"Get-ItemPropertyValue" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gps" ,
"Get-Process" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "group" ,
"Group-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gsv" ,
"Get-Service" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gu" ,
"Get-Unique" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gv" ,
"Get-Variable" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "iex" ,
"Invoke-Expression" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ihy" ,
"Invoke-History" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ii" ,
"Invoke-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ipmo" ,
"Import-Module" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ipal" ,
"Import-Alias" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ipcsv" ,
"Import-Csv" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "measure" ,
"Measure-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "mi" ,
"Move-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "mp" ,
"Move-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "nal" ,
"New-Alias" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ndr" ,
"New-PSDrive" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ni" ,
"New-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "nv" ,
"New-Variable" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "nmo" ,
"New-Module" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "oh" ,
"Out-Host" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rbp" ,
"Remove-PSBreakpoint" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rdr" ,
"Remove-PSDrive" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ri" ,
"Remove-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rni" ,
"Rename-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rnp" ,
"Rename-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rp" ,
"Remove-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rmo" ,
"Remove-Module" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rv" ,
"Remove-Variable" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rvpa" ,
"Resolve-Path" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sal" ,
"Set-Alias" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sasv" ,
"Start-Service" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sbp" ,
"Set-PSBreakpoint" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sc" ,
"Set-Content" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
// this conflicts with sd.exe, and makes msh unusable by dev.
// new SessionStateAliasEntry("sd",
// "Set-Date", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.Constant | ScopedItemOptions.AllScope),
new SessionStateAliasEntry ( "select" ,
"Select-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "si" ,
"Set-Item" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sl" ,
"Set-Location" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sp" ,
"Set-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "saps" ,
"Start-Process" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "spps" ,
"Stop-Process" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "spsv" ,
"Stop-Service" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sv" ,
"Set-Variable" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
2016-07-22 19:49:45 +02:00
// Porting note: #if !UNIX is used to disable alises for cmdlets which conflict with Linux / OS X
#if ! UNIX
2016-04-08 01:05:06 +02:00
// ac is a native command on OS X
new SessionStateAliasEntry ( "ac" ,
"Add-Content" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "compare" ,
"Compare-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "cpp" ,
"Copy-ItemProperty" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "diff" ,
"Compare-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sleep" ,
"Start-Sleep" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sort" ,
"Sort-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "start" ,
"Start-Process" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
2016-03-30 23:20:52 +02:00
new SessionStateAliasEntry ( "tee" ,
"Tee-Object" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "write" ,
"Write-Output" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
2016-04-08 01:05:06 +02:00
// These were traqnsferred from the "transferred from the profile" section
new SessionStateAliasEntry ( "cat" ,
"Get-Content" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "cp" ,
"Copy-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ls" ,
"Get-ChildItem" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "man" ,
"help" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "mount" ,
"New-PSDrive" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "mv" ,
"Move-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ps" ,
"Get-Process" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rm" ,
"Remove-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rmdir" ,
"Remove-Item" , "" , ScopedItemOptions . AllScope ) ,
#endif
// Bash built-ins we purposefully keep even if they override native commands
new SessionStateAliasEntry ( "cd" ,
"Set-Location" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "dir" ,
"Get-ChildItem" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "echo" ,
"Write-Output" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "fc" ,
"Format-Custom" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "kill" ,
"Stop-Process" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "pwd" ,
"Get-Location" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "type" ,
"Get-Content" , "" , ScopedItemOptions . AllScope ) ,
// Native commands we keep because the functions act correctly on Linux
new SessionStateAliasEntry ( "clear" ,
"Clear-Host" , "" , ScopedItemOptions . AllScope ) ,
2016-03-30 23:20:52 +02:00
//#if !CORECLR is used to disable aliases for cmdlets which are not available on OneCore
#if ! CORECLR
new SessionStateAliasEntry ( "asnp" ,
"Add-PSSnapIn" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gsnp" ,
"Get-PSSnapIn" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gwmi" ,
"Get-WmiObject" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "irm" ,
"Invoke-RestMethod" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "iwr" ,
"Invoke-WebRequest" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "iwmi" ,
"Invoke-WMIMethod" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ogv" ,
"Out-GridView" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ise" ,
"powershell_ise.exe" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rsnp" ,
"Remove-PSSnapin" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rwmi" ,
"Remove-WMIObject" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "swmi" ,
"Set-WMIInstance" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "shcm" ,
"Show-Command" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "trcm" ,
"Trace-Command" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "wget" ,
"Invoke-WebRequest" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "curl" ,
"Invoke-WebRequest" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "lp" ,
"Out-Printer" , "" , ScopedItemOptions . AllScope ) ,
#endif
// Aliases transferred from the profile
new SessionStateAliasEntry ( "h" ,
"Get-History" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "history" ,
"Get-History" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "md" ,
"mkdir" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "popd" ,
"Pop-Location" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "pushd" ,
"Push-Location" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "r" ,
"Invoke-History" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "cls" ,
"Clear-Host" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "chdir" ,
"Set-Location" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "copy" ,
"Copy-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "del" ,
"Remove-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "erase" ,
"Remove-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "move" ,
"Move-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rd" ,
"Remove-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ren" ,
"Rename-Item" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "set" ,
"Set-Variable" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "icm" ,
"Invoke-Command" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "clhy" ,
"Clear-History" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
// Job Specific aliases
new SessionStateAliasEntry ( "gjb" ,
"Get-Job" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rcjb" ,
"Receive-Job" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rjb" ,
"Remove-Job" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "sajb" ,
"Start-Job" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "spjb" ,
"Stop-Job" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "wjb" ,
"Wait-Job" , "" , ScopedItemOptions . AllScope ) ,
#if ! CORECLR
new SessionStateAliasEntry ( "sujb" ,
"Suspend-Job" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rujb" ,
"Resume-Job" , "" , ScopedItemOptions . AllScope ) ,
// Remoting Cmdlets Specific aliases
new SessionStateAliasEntry ( "npssc" ,
"New-PSSessionConfigurationFile" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "ipsn" ,
"Import-PSSession" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "epsn" ,
"Export-PSSession" , "" , ScopedItemOptions . AllScope ) ,
#endif
new SessionStateAliasEntry ( "cnsn" ,
"Connect-PSSession" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "dnsn" ,
"Disconnect-PSSession" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "nsn" ,
"New-PSSession" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "gsn" ,
"Get-PSSession" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rsn" ,
"Remove-PSSession" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "etsn" ,
"Enter-PSSession" , "" , ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "rcsn" ,
"Receive-PSSession" , "" , ScopedItemOptions . ReadOnly | ScopedItemOptions . AllScope ) ,
new SessionStateAliasEntry ( "exsn" ,
"Exit-PSSession" , "" , ScopedItemOptions . AllScope ) ,
// Win8: 121662/169179 Add "sls" alias for Select-String cmdlet
// - do not use AllScope - this causes errors in profiles that set this somewhat commonly used alias.
new SessionStateAliasEntry ( "sls" ,
"Select-String" , "" , ScopedItemOptions . None ) ,
} ;
}
}
internal const string DefaultPromptFunctionText = @ "
"" PS $ ( $ executionContext . SessionState . Path . CurrentLocation ) $ ( '>' * ( $ nestedPromptLevel + 1 ) ) "" ;
# . Link
# http : //go.microsoft.com/fwlink/?LinkID=225750
# . ExternalHelp System . Management . Automation . dll - help . xml
";
internal const string DefaultMoreFunctionText = @ "
param ( [ string [ ] ] $ paths )
2016-04-28 22:41:25 +02:00
# Nano needs to use Unicode , but Windows and Linux need the default
2016-07-22 01:52:22 +02:00
$ OutputEncoding = if ( $ IsWindows - and $ IsCoreCLR ) {
2016-04-28 22:41:25 +02:00
[System.Text.Encoding] : : Unicode
} else {
[System.Console] : : OutputEncoding
}
2016-04-09 06:20:57 +02:00
# Respect PAGER , use more on Windows , and use less on Linux
if ( Test - Path env : PAGER ) {
2016-07-06 01:02:06 +02:00
$ moreCommand = ( Get - Command - CommandType Application $ env : PAGER | Select - Object - First 1 ) . Definition
2016-04-09 06:20:57 +02:00
} elseif ( $ IsWindows ) {
2016-07-06 01:02:06 +02:00
$ moreCommand = ( Get - Command - CommandType Application more | Select - Object - First 1 ) . Definition
2016-04-09 06:20:57 +02:00
} else {
2016-07-06 01:02:06 +02:00
$ moreCommand = ( Get - Command - CommandType Application less | Select - Object - First 1 ) . Definition
2016-04-09 06:20:57 +02:00
}
2016-03-30 23:20:52 +02:00
if ( $ paths ) {
2016-04-09 06:20:57 +02:00
foreach ( $ file in $ paths ) {
2016-04-06 21:01:07 +02:00
Get - Content $ file | & $ moreCommand
2016-03-30 23:20:52 +02:00
}
2016-04-06 21:01:07 +02:00
} else { $ input | & $ moreCommand }
2016-03-30 23:20:52 +02:00
";
internal const string DefaultSetDriveFunctionText = "Set-Location $MyInvocation.MyCommand.Name" ;
2016-06-22 04:17:13 +02:00
internal static ScriptBlock SetDriveScriptBlock = ScriptBlock . CreateDelayParsedScriptBlock ( DefaultSetDriveFunctionText , isProductCode : true ) ;
2016-03-30 23:20:52 +02:00
internal static SessionStateFunctionEntry [ ] BuiltInFunctions = new SessionStateFunctionEntry [ ]
{
// Functions. Only the name and definitions are used
2016-07-29 22:02:49 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "prompt" , DefaultPromptFunctionText , isProductCode : true ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "TabExpansion2" , s_tabExpansionFunctionText , isProductCode : true ) ,
2016-06-22 04:17:13 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "Clear-Host" , GetClearHostFunctionText ( ) , isProductCode : true ) ,
2016-04-08 01:05:06 +02:00
// Porting note: we keep more because the function acts correctly on Linux
2016-06-22 04:17:13 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "more" , DefaultMoreFunctionText , isProductCode : true ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "help" , GetHelpPagingFunctionText ( ) , isProductCode : true ) ,
2016-04-08 01:05:06 +02:00
// Porting note: we remove mkdir on Linux because it is a conflict
2016-07-22 19:49:45 +02:00
#if ! UNIX
2016-06-22 04:17:13 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "mkdir" , GetMkdirFunctionText ( ) , isProductCode : true ) ,
2016-04-08 01:05:06 +02:00
#endif
2016-06-22 04:17:13 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "Get-Verb" , GetGetVerbText ( ) , isProductCode : true ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "oss" , GetOSTFunctionText ( ) , isProductCode : true ) ,
2016-03-30 23:20:52 +02:00
2016-04-08 21:50:53 +02:00
// Porting note: we remove the drive functions from Linux because they make no sense
2016-07-22 19:49:45 +02:00
#if ! UNIX
2016-03-30 23:20:52 +02:00
// Default drives
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "A:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "B:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "C:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "D:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "E:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "F:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "G:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "H:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "I:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "J:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "K:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "L:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "M:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "N:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "O:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "P:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "Q:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "R:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "S:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "T:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "U:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "V:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "W:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "X:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "Y:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "Z:" , DefaultSetDriveFunctionText , SetDriveScriptBlock ) ,
2016-04-08 21:50:53 +02:00
#endif
2016-03-30 23:20:52 +02:00
2016-06-22 04:17:13 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "cd.." , "Set-Location .." , isProductCode : true ) ,
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "cd\\" , "Set-Location \\" , isProductCode : true ) ,
2016-03-30 23:20:52 +02:00
// Win8: 320909. Retaining the original definition to ensure backward compatability.
2016-07-29 22:02:49 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "ImportSystemModules" , s_importSystemModulesText , isProductCode : true ) ,
2016-03-30 23:20:52 +02:00
SessionStateFunctionEntry . GetDelayParsedFunctionEntry ( "Pause" ,
2016-06-22 04:17:13 +02:00
string . Concat ( "$null = Read-Host '" , CodeGeneration . EscapeSingleQuotedStringContent ( RunspaceInit . PauseDefinitionString ) , "'" ) , isProductCode : true )
2016-03-30 23:20:52 +02:00
} ;
2016-08-03 04:00:50 +02:00
internal static void RemoveAllDrivesForProvider ( ProviderInfo pi , SessionStateInternal ssi )
2016-03-30 23:20:52 +02:00
{
foreach ( PSDriveInfo di in ssi . GetDrivesForProvider ( pi . FullName ) )
{
try
{
ssi . RemoveDrive ( di , true , null ) ;
}
catch ( Exception e )
{
CommandProcessorBase . CheckForSevereException ( e ) ;
}
}
}
2016-08-03 04:00:50 +02:00
private static PSTraceSource s_PSSnapInTracer = PSTraceSource . GetTracer ( "PSSnapInLoadUnload" , "Loading and unloading mshsnapins" , false ) ;
2016-03-30 23:20:52 +02:00
internal static string CoreSnapin = "Microsoft.PowerShell.Core" ;
internal static string CoreModule = "Microsoft.PowerShell.Core" ;
internal Collection < PSSnapInInfo > defaultSnapins = new Collection < PSSnapInInfo > ( ) ;
// The list of engine modules to create warnings when you try to remove them
internal static HashSet < string > EngineModules = new HashSet < string > ( StringComparer . OrdinalIgnoreCase )
{
"Microsoft.PowerShell.Utility" ,
"Microsoft.PowerShell.Management" ,
"Microsoft.PowerShell.Diagnostics" ,
2016-05-28 01:16:34 +02:00
"Microsoft.PowerShell.Host" ,
2016-03-30 23:20:52 +02:00
"Microsoft.PowerShell.Security" ,
"Microsoft.WSMan.Management"
} ;
2016-08-03 04:00:50 +02:00
internal static HashSet < string > NestedEngineModules = new HashSet < string > ( StringComparer . OrdinalIgnoreCase )
2016-03-30 23:20:52 +02:00
{
"Microsoft.PowerShell.Commands.Utility" ,
"Microsoft.PowerShell.Commands.Management" ,
"Microsoft.PowerShell.Commands.Diagnostics" ,
"Microsoft.PowerShell.ConsoleHost"
} ;
internal static Dictionary < string , string > EngineModuleNestedModuleMapping = new Dictionary < string , string > ( StringComparer . OrdinalIgnoreCase )
{
{ "Microsoft.PowerShell.Utility" , "Microsoft.PowerShell.Commands.Utility" } ,
{ "Microsoft.PowerShell.Management" , "Microsoft.PowerShell.Commands.Management" } ,
{ "Microsoft.PowerShell.Diagnostics" , "Microsoft.PowerShell.Commands.Diagnostics" } ,
2016-05-28 01:16:34 +02:00
{ "Microsoft.PowerShell.Host" , "Microsoft.PowerShell.ConsoleHost" } ,
2016-03-30 23:20:52 +02:00
} ;
internal static Dictionary < string , string > NestedModuleEngineModuleMapping = new Dictionary < string , string > ( StringComparer . OrdinalIgnoreCase )
{
{ "Microsoft.PowerShell.Commands.Utility" , "Microsoft.PowerShell.Utility" } ,
{ "Microsoft.PowerShell.Commands.Management" , "Microsoft.PowerShell.Management" } ,
{ "Microsoft.PowerShell.Commands.Diagnostics" , "Microsoft.PowerShell.Diagnostics" } ,
2016-05-28 01:16:34 +02:00
{ "Microsoft.PowerShell.ConsoleHost" , "Microsoft.PowerShell.Host" } ,
2016-03-30 23:20:52 +02:00
{ "Microsoft.PowerShell.Security" , "Microsoft.PowerShell.Security" } ,
{ "Microsoft.WSMan.Management" , "Microsoft.WSMan.Management" } ,
} ;
// The list of engine modules that we will not allow users to remove
internal static HashSet < string > ConstantEngineModules = new HashSet < string > ( StringComparer . OrdinalIgnoreCase )
{
CoreModule ,
} ;
// The list of nested engine modules that we will not allow users to remove
internal static HashSet < string > ConstantEngineNestedModules = new HashSet < string > ( StringComparer . OrdinalIgnoreCase )
{
"System.Management.Automation" ,
} ;
internal static string GetNestedModuleDllName ( string moduleName )
{
string result = null ;
if ( ! EngineModuleNestedModuleMapping . TryGetValue ( moduleName , out result ) )
{
result = string . Empty ;
}
return result ;
}
internal void SaveAsConsoleFile ( string path )
{
if ( null = = path )
{
throw PSTraceSource . NewArgumentNullException ( "path" ) ;
}
if ( ! path . EndsWith ( StringLiterals . PowerShellConsoleFileExtension , StringComparison . OrdinalIgnoreCase ) )
{
throw PSTraceSource . NewArgumentException ( "path" , ConsoleInfoErrorStrings . BadConsoleExtension ) ;
}
//ConsoleFileElement will write to file
PSConsoleFileElement . WriteToFile ( path , PSVersionInfo . PSVersion , this . ImportedSnapins . Values ) ;
}
}
/// <summary>
/// Set of helper methods fro loading assemblies containing cmdlets...
/// </summary>
internal static class PSSnapInHelpers
{
[SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom")]
internal static Assembly LoadPSSnapInAssembly ( PSSnapInInfo psSnapInInfo ,
2016-07-29 22:02:49 +02:00
out Dictionary < string , SessionStateCmdletEntry > cmdlets , out Dictionary < string , SessionStateProviderEntry > providers )
2016-03-30 23:20:52 +02:00
{
Assembly assembly = null ;
cmdlets = null ;
providers = null ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly from GAC. Assembly Name: {0}" , psSnapInInfo . AssemblyName ) ;
2016-03-30 23:20:52 +02:00
try
{
2016-04-06 21:01:07 +02:00
// WARNING: DUPLICATE CODE see RunspaceConfigForSingleShell
2016-06-25 01:28:37 +02:00
assembly = Assembly . Load ( new AssemblyName ( psSnapInInfo . AssemblyName ) ) ;
2016-03-30 23:20:52 +02:00
}
catch ( BadImageFormatException e )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceWarning ( "Not able to load assembly {0}: {1}" , psSnapInInfo . AssemblyName , e . Message ) ;
2016-03-30 23:20:52 +02:00
}
catch ( FileNotFoundException e )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceWarning ( "Not able to load assembly {0}: {1}" , psSnapInInfo . AssemblyName , e . Message ) ;
2016-03-30 23:20:52 +02:00
}
catch ( FileLoadException e )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceWarning ( "Not able to load assembly {0}: {1}" , psSnapInInfo . AssemblyName , e . Message ) ;
2016-03-30 23:20:52 +02:00
}
if ( assembly ! = null )
return assembly ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Loading assembly from path: {0}" , psSnapInInfo . AssemblyName ) ;
2016-03-30 23:20:52 +02:00
try
{
AssemblyName assemblyName = ClrFacade . GetAssemblyName ( psSnapInInfo . AbsoluteModulePath ) ;
2016-04-06 21:01:07 +02:00
2016-07-22 01:03:37 +02:00
if ( ! string . Equals ( assemblyName . FullName , psSnapInInfo . AssemblyName , StringComparison . OrdinalIgnoreCase ) )
2016-03-30 23:20:52 +02:00
{
string message = StringUtil . Format ( ConsoleInfoErrorStrings . PSSnapInAssemblyNameMismatch , psSnapInInfo . AbsoluteModulePath , psSnapInInfo . AssemblyName ) ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( psSnapInInfo . Name , message ) ;
}
assembly = ClrFacade . LoadFrom ( psSnapInInfo . AbsoluteModulePath ) ;
}
catch ( FileLoadException e )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "Not able to load assembly {0}: {1}" , psSnapInInfo . AssemblyName , e . Message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( psSnapInInfo . Name , e . Message ) ;
}
catch ( BadImageFormatException e )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "Not able to load assembly {0}: {1}" , psSnapInInfo . AssemblyName , e . Message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( psSnapInInfo . Name , e . Message ) ;
}
catch ( FileNotFoundException e )
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( "Not able to load assembly {0}: {1}" , psSnapInInfo . AssemblyName , e . Message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( psSnapInInfo . Name , e . Message ) ;
}
return assembly ;
}
private static T GetCustomAttribute < T > ( TypeInfo decoratedType ) where T : Attribute
{
var attributes = CustomAttributeExtensions . GetCustomAttributes < T > ( decoratedType , false ) ;
var customAttrs = attributes . ToArray ( ) ;
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
Debug . Assert ( customAttrs . Length < = 1 , "CmdletAttribute and/or CmdletProviderAttribute cannot normally appear more than once" ) ;
return customAttrs . Length = = 0 ? null : customAttrs [ 0 ] ;
}
internal static void AnalyzePSSnapInAssembly ( Assembly assembly , string name , PSSnapInInfo psSnapInInfo , PSModuleInfo moduleInfo , bool isModuleLoad ,
2016-07-29 22:02:49 +02:00
out Dictionary < string , SessionStateCmdletEntry > cmdlets , out Dictionary < string , List < SessionStateAliasEntry > > aliases ,
2016-03-30 23:20:52 +02:00
out Dictionary < string , SessionStateProviderEntry > providers , out string helpFile )
{
helpFile = null ;
if ( assembly = = null )
{
throw new ArgumentNullException ( "assembly" ) ;
}
cmdlets = null ;
aliases = null ;
providers = null ;
// See if this assembly has already been scanned...
Dictionary < string , Tuple < SessionStateCmdletEntry , List < SessionStateAliasEntry > > > cachedCmdlets ;
2016-07-29 22:02:49 +02:00
if ( s_cmdletCache . Value . TryGetValue ( assembly , out cachedCmdlets ) )
2016-03-30 23:20:52 +02:00
{
2016-07-29 22:02:49 +02:00
cmdlets = new Dictionary < string , SessionStateCmdletEntry > ( s_cmdletCache . Value . Count , StringComparer . OrdinalIgnoreCase ) ;
2016-03-30 23:20:52 +02:00
aliases = new Dictionary < string , List < SessionStateAliasEntry > > ( StringComparer . OrdinalIgnoreCase ) ;
foreach ( var pair in cachedCmdlets )
{
var key = pair . Key ;
var entry = pair . Value ;
if ( entry . Item1 . PSSnapIn = = null & & psSnapInInfo ! = null )
{
entry . Item1 . SetPSSnapIn ( psSnapInInfo ) ;
}
var newEntry = ( SessionStateCmdletEntry ) entry . Item1 . Clone ( ) ;
if ( newEntry . PSSnapIn ! = null & & psSnapInInfo = = null )
{
newEntry . SetPSSnapIn ( null ) ;
}
cmdlets [ key ] = newEntry ;
if ( entry . Item2 ! = null )
{
var aliasList = new List < SessionStateAliasEntry > ( ) ;
foreach ( var alias in entry . Item2 )
{
if ( alias . PSSnapIn = = null & & psSnapInInfo ! = null )
{
alias . SetPSSnapIn ( psSnapInInfo ) ;
}
2016-07-29 22:02:49 +02:00
var newAliasEntry = ( SessionStateAliasEntry ) alias . Clone ( ) ;
2016-03-30 23:20:52 +02:00
if ( newAliasEntry . PSSnapIn ! = null & & psSnapInInfo = = null )
{
newAliasEntry . SetPSSnapIn ( null ) ;
}
aliasList . Add ( newAliasEntry ) ;
}
aliases [ key ] = aliasList ;
}
}
}
Dictionary < string , SessionStateProviderEntry > cachedProviders ;
2016-07-29 22:02:49 +02:00
if ( s_providerCache . Value . TryGetValue ( assembly , out cachedProviders ) )
2016-03-30 23:20:52 +02:00
{
2016-07-29 22:02:49 +02:00
providers = new Dictionary < string , SessionStateProviderEntry > ( s_providerCache . Value . Count , StringComparer . OrdinalIgnoreCase ) ;
2016-03-30 23:20:52 +02:00
foreach ( var pair in cachedProviders )
{
var key = pair . Key ;
var entry = pair . Value ;
if ( entry . PSSnapIn = = null & & psSnapInInfo ! = null )
{
entry . SetPSSnapIn ( psSnapInInfo ) ;
}
var newEntry = ( SessionStateProviderEntry ) entry . Clone ( ) ;
if ( newEntry . PSSnapIn ! = null & & psSnapInInfo = = null )
{
newEntry . SetPSSnapIn ( null ) ;
}
providers [ key ] = newEntry ;
}
}
2016-04-28 22:41:25 +02:00
string assemblyPath = assembly . Location ;
2016-03-30 23:20:52 +02:00
Type [ ] assemblyTypes ;
if ( cmdlets ! = null | | providers ! = null )
{
2016-07-29 22:02:49 +02:00
if ( ! s_assembliesWithModuleInitializerCache . Value . ContainsKey ( assembly ) )
2016-03-30 23:20:52 +02:00
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Returning cached cmdlet and provider entries for {0}" , assemblyPath ) ;
2016-03-30 23:20:52 +02:00
return ;
}
else
{
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Executing IModuleAssemblyInitializer.Import for {0}" , assemblyPath ) ;
2016-03-30 23:20:52 +02:00
assemblyTypes = GetAssemblyTypes ( assembly , name ) ;
ExecuteModuleInitializer ( assembly , assemblyTypes , isModuleLoad ) ;
return ;
}
}
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "Analyzing assembly {0} for cmdlet and providers" , assemblyPath ) ;
2016-03-30 23:20:52 +02:00
helpFile = GetHelpFile ( assemblyPath ) ;
Type randomCmdletToCheckLinkDemand = null ;
Type randomProviderToCheckLinkDemand = null ;
if ( psSnapInInfo ! = null & & psSnapInInfo . Name . Equals ( InitialSessionState . CoreSnapin , StringComparison . OrdinalIgnoreCase ) )
{
InitializeCoreCmdletsAndProviders ( psSnapInInfo , out cmdlets , out providers , helpFile ) ;
#if DEBUG
// Make sure the pre-built cmdlet and provider tables match what reflection finds. This will help
// avoid issues where you add a cmdlet but forget to update the table in InitializeCoreCmdletsAndProviders.
Dictionary < string , SessionStateCmdletEntry > cmdletsCheck = null ;
Dictionary < string , SessionStateProviderEntry > providersCheck = null ;
Dictionary < string , List < SessionStateAliasEntry > > aliasesCheck = null ;
Type unused1 = null ;
Type unused2 = null ;
AnalyzeModuleAssemblyWithReflection ( assembly , name , psSnapInInfo , moduleInfo , isModuleLoad ,
ref cmdletsCheck , ref aliasesCheck , ref providersCheck , helpFile , ref unused1 , ref unused2 ) ;
Diagnostics . Assert ( aliasesCheck = = null , "InitializeCoreCmdletsAndProviders assumes no aliases are defined in System.Management.Automation.dll" ) ;
Diagnostics . Assert ( providersCheck . Keys . Count = = providers . Keys . Count , "new Provider added to System.Management.Automation.dll - update InitializeCoreCmdletsAndProviders" ) ;
foreach ( var pair in providersCheck )
{
SessionStateProviderEntry other ;
if ( providers . TryGetValue ( pair . Key , out other ) )
{
Diagnostics . Assert ( ( object ) pair . Value . HelpFileName = = ( object ) other . HelpFileName , "Pre-generated Provider help file incorrect" ) ;
Diagnostics . Assert ( pair . Value . ImplementingType = = other . ImplementingType , "Pre-generated Provider implementing type incorrect" ) ;
Diagnostics . Assert ( string . Equals ( pair . Value . Name , other . Name , StringComparison . Ordinal ) , "Pre-generated Provider name incorrect" ) ;
Diagnostics . Assert ( pair . Value . PSSnapIn = = other . PSSnapIn , "Pre-generated Provider snappin type incorrect" ) ;
Diagnostics . Assert ( pair . Value . Module = = other . Module , "Pre-generated Provider module incorrect" ) ;
Diagnostics . Assert ( pair . Value . Visibility = = other . Visibility , "Pre-generated Provider visibility incorrect" ) ;
}
else
{
Diagnostics . Assert ( false , "Missing provider: " + pair . Key ) ;
}
}
Diagnostics . Assert ( cmdletsCheck . Keys . Count = = cmdlets . Keys . Count , "new Cmdlet added to System.Management.Automation.dll - update InitializeCoreCmdletsAndProviders" ) ;
foreach ( var pair in cmdletsCheck )
{
SessionStateCmdletEntry other ;
if ( cmdlets . TryGetValue ( pair . Key , out other ) )
{
Diagnostics . Assert ( ( object ) pair . Value . HelpFileName = = ( object ) other . HelpFileName , "Pre-generated Provider help file incorrect" ) ;
Diagnostics . Assert ( pair . Value . ImplementingType = = other . ImplementingType , "Pre-generated Provider implementing type incorrect" ) ;
Diagnostics . Assert ( string . Equals ( pair . Value . Name , other . Name , StringComparison . Ordinal ) , "Pre-generated Provider name incorrect" ) ;
Diagnostics . Assert ( pair . Value . PSSnapIn = = other . PSSnapIn , "Pre-generated Provider snappin type incorrect" ) ;
Diagnostics . Assert ( pair . Value . Module = = other . Module , "Pre-generated Provider module incorrect" ) ;
Diagnostics . Assert ( pair . Value . Visibility = = other . Visibility , "Pre-generated Provider visibility incorrect" ) ;
}
else
{
Diagnostics . Assert ( false , "Pre-generated Cmdlet missing: " + pair . Key ) ;
}
}
#endif
}
else
{
AnalyzeModuleAssemblyWithReflection ( assembly , name , psSnapInInfo , moduleInfo , isModuleLoad ,
ref cmdlets , ref aliases , ref providers , helpFile , ref randomCmdletToCheckLinkDemand , ref randomProviderToCheckLinkDemand ) ;
}
// force a LinkDemand check to get an explicit exception if
// Cmdlet[Provider]Attributes are silently swallowed by Type.GetCustomAttributes
// bug Win7:705573
if ( ( providers = = null | | providers . Count = = 0 ) & & ( cmdlets = = null | | cmdlets . Count = = 0 ) )
{
try
{
if ( randomCmdletToCheckLinkDemand ! = null )
{
ConstructorInfo constructor = randomCmdletToCheckLinkDemand . GetConstructor ( PSTypeExtensions . EmptyTypes ) ;
if ( constructor ! = null )
{
constructor . Invoke ( null ) ; // this is how we artificially force a LinkDemand check
}
}
if ( randomProviderToCheckLinkDemand ! = null )
{
ConstructorInfo constructor = randomProviderToCheckLinkDemand . GetConstructor ( PSTypeExtensions . EmptyTypes ) ;
if ( constructor ! = null )
{
constructor . Invoke ( null ) ; // this is how we artificially force a LinkDemand check
}
}
}
catch ( TargetInvocationException e )
{
throw e . InnerException ;
}
}
2016-07-29 22:02:49 +02:00
2016-03-30 23:20:52 +02:00
// Cache the cmdlet and provider info for this assembly...
// We need to cache a clone of this data *before* the
// module info is set on it since module info can't be shared
// across runspaces. When these entries are hit in the cache,
// copies will be returned to ensure that the cache is never tied to a runspace.
if ( cmdlets ! = null )
{
var clone = new Dictionary < string , Tuple < SessionStateCmdletEntry , List < SessionStateAliasEntry > > > ( cmdlets . Count , StringComparer . OrdinalIgnoreCase ) ;
List < SessionStateAliasEntry > aliasesCloneList = null ;
foreach ( var entry in cmdlets )
{
List < SessionStateAliasEntry > aliasEntries ;
if ( aliases ! = null & & aliases . TryGetValue ( entry . Key , out aliasEntries ) )
{
aliasesCloneList = new List < SessionStateAliasEntry > ( aliases . Count ) ;
foreach ( var aliasEntry in aliasEntries )
{
aliasesCloneList . Add ( ( SessionStateAliasEntry ) aliasEntry . Clone ( ) ) ;
}
}
clone [ entry . Key ] = new Tuple < SessionStateCmdletEntry , List < SessionStateAliasEntry > > ( ( SessionStateCmdletEntry ) entry . Value . Clone ( ) , aliasesCloneList ) ;
}
2016-07-29 22:02:49 +02:00
s_cmdletCache . Value [ assembly ] = clone ;
2016-03-30 23:20:52 +02:00
}
if ( providers ! = null )
{
var clone = new Dictionary < string , SessionStateProviderEntry > ( providers . Count , StringComparer . OrdinalIgnoreCase ) ;
foreach ( var entry in providers )
{
2016-07-29 22:02:49 +02:00
clone [ entry . Key ] = ( SessionStateProviderEntry ) entry . Value . Clone ( ) ;
2016-03-30 23:20:52 +02:00
}
2016-07-29 22:02:49 +02:00
s_providerCache . Value [ assembly ] = providers ;
2016-03-30 23:20:52 +02:00
}
}
private static void AnalyzeModuleAssemblyWithReflection ( Assembly assembly , string name , PSSnapInInfo psSnapInInfo ,
PSModuleInfo moduleInfo , bool isModuleLoad ,
ref Dictionary < string , SessionStateCmdletEntry > cmdlets ,
ref Dictionary < string , List < SessionStateAliasEntry > > aliases ,
ref Dictionary < string , SessionStateProviderEntry > providers ,
string helpFile ,
ref Type randomCmdletToCheckLinkDemand ,
ref Type randomProviderToCheckLinkDemand )
{
var assemblyTypes = GetAssemblyTypes ( assembly , name ) ;
ExecuteModuleInitializer ( assembly , assemblyTypes , isModuleLoad ) ;
foreach ( Type type in assemblyTypes )
{
var typeInfo = type . GetTypeInfo ( ) ;
if ( ! ( typeInfo . IsPublic | | typeInfo . IsNestedPublic ) | | typeInfo . IsAbstract )
continue ;
// Check for cmdlets
if ( IsCmdletClass ( type ) & & HasDefaultConstructor ( type ) )
{
randomCmdletToCheckLinkDemand = type ;
CmdletAttribute cmdletAttribute = GetCustomAttribute < CmdletAttribute > ( typeInfo ) ;
if ( cmdletAttribute = = null )
{
continue ;
}
string cmdletName = GetCmdletName ( cmdletAttribute ) ;
if ( string . IsNullOrEmpty ( cmdletName ) )
{
continue ;
}
if ( cmdlets ! = null & & cmdlets . ContainsKey ( cmdletName ) )
{
string message = StringUtil . Format ( ConsoleInfoErrorStrings . PSSnapInDuplicateCmdlets , cmdletName , name ) ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( name , message ) ;
}
SessionStateCmdletEntry cmdlet = new SessionStateCmdletEntry ( cmdletName , type , helpFile ) ;
cmdlet . SetPSSnapIn ( psSnapInInfo ) ;
if ( cmdlets = = null )
{
cmdlets = new Dictionary < string , SessionStateCmdletEntry > ( StringComparer . OrdinalIgnoreCase ) ;
}
cmdlets . Add ( cmdletName , cmdlet ) ;
var aliasAttribute = GetCustomAttribute < AliasAttribute > ( typeInfo ) ;
if ( aliasAttribute ! = null )
{
if ( aliases = = null )
{
aliases = new Dictionary < string , List < SessionStateAliasEntry > > ( StringComparer . OrdinalIgnoreCase ) ;
}
var aliasList = new List < SessionStateAliasEntry > ( ) ;
foreach ( var alias in aliasAttribute . AliasNames )
{
var aliasEntry = new SessionStateAliasEntry ( alias , cmdletName , "" , ScopedItemOptions . None ) ;
if ( psSnapInInfo ! = null )
{
aliasEntry . SetPSSnapIn ( psSnapInInfo ) ;
}
aliasList . Add ( aliasEntry ) ;
}
aliases . Add ( cmdletName , aliasList ) ;
}
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "{0} from type {1} is added as a cmdlet. " , cmdletName , type . FullName ) ;
2016-03-30 23:20:52 +02:00
continue ;
}
// Check for providers
if ( IsProviderClass ( type ) & & HasDefaultConstructor ( type ) )
{
randomProviderToCheckLinkDemand = type ;
CmdletProviderAttribute providerAttribute = GetCustomAttribute < CmdletProviderAttribute > ( typeInfo ) ;
if ( providerAttribute = = null )
{
continue ;
}
string providerName = GetProviderName ( providerAttribute ) ;
if ( string . IsNullOrEmpty ( providerName ) )
{
continue ;
}
if ( providers ! = null & & providers . ContainsKey ( providerName ) )
{
string message = StringUtil . Format ( ConsoleInfoErrorStrings . PSSnapInDuplicateProviders , providerName , psSnapInInfo . Name ) ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( psSnapInInfo . Name , message ) ;
}
SessionStateProviderEntry provider = new SessionStateProviderEntry ( providerName , type , helpFile ) ;
provider . SetPSSnapIn ( psSnapInInfo ) ;
// After converting core snapins to load as modules, the providers will have Module property populated
if ( moduleInfo ! = null )
{
provider . SetModule ( moduleInfo ) ;
}
if ( providers = = null )
{
providers = new Dictionary < string , SessionStateProviderEntry > ( StringComparer . OrdinalIgnoreCase ) ;
}
providers . Add ( providerName , provider ) ;
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . WriteLine ( "{0} from type {1} is added as a provider. " , providerName , type . FullName ) ;
2016-03-30 23:20:52 +02:00
}
}
}
private static void InitializeCoreCmdletsAndProviders (
PSSnapInInfo psSnapInInfo ,
out Dictionary < string , SessionStateCmdletEntry > cmdlets ,
out Dictionary < string , SessionStateProviderEntry > providers ,
string helpFile )
{
cmdlets = new Dictionary < string , SessionStateCmdletEntry > ( StringComparer . OrdinalIgnoreCase )
{
{ "Add-History" , new SessionStateCmdletEntry ( "Add-History" , typeof ( AddHistoryCommand ) , helpFile ) } ,
{ "Clear-History" , new SessionStateCmdletEntry ( "Clear-History" , typeof ( ClearHistoryCommand ) , helpFile ) } ,
{ "Connect-PSSession" , new SessionStateCmdletEntry ( "Connect-PSSession" , typeof ( ConnectPSSessionCommand ) , helpFile ) } ,
{ "Debug-Job" , new SessionStateCmdletEntry ( "Debug-Job" , typeof ( DebugJobCommand ) , helpFile ) } ,
{ "Disable-PSSessionConfiguration" , new SessionStateCmdletEntry ( "Disable-PSSessionConfiguration" , typeof ( DisablePSSessionConfigurationCommand ) , helpFile ) } ,
{ "Disconnect-PSSession" , new SessionStateCmdletEntry ( "Disconnect-PSSession" , typeof ( DisconnectPSSessionCommand ) , helpFile ) } ,
{ "Enable-PSSessionConfiguration" , new SessionStateCmdletEntry ( "Enable-PSSessionConfiguration" , typeof ( EnablePSSessionConfigurationCommand ) , helpFile ) } ,
{ "Enter-PSHostProcess" , new SessionStateCmdletEntry ( "Enter-PSHostProcess" , typeof ( EnterPSHostProcessCommand ) , helpFile ) } ,
{ "Enter-PSSession" , new SessionStateCmdletEntry ( "Enter-PSSession" , typeof ( EnterPSSessionCommand ) , helpFile ) } ,
{ "Exit-PSHostProcess" , new SessionStateCmdletEntry ( "Exit-PSHostProcess" , typeof ( ExitPSHostProcessCommand ) , helpFile ) } ,
{ "Exit-PSSession" , new SessionStateCmdletEntry ( "Exit-PSSession" , typeof ( ExitPSSessionCommand ) , helpFile ) } ,
{ "Export-ModuleMember" , new SessionStateCmdletEntry ( "Export-ModuleMember" , typeof ( ExportModuleMemberCommand ) , helpFile ) } ,
{ "ForEach-Object" , new SessionStateCmdletEntry ( "ForEach-Object" , typeof ( ForEachObjectCommand ) , helpFile ) } ,
{ "Get-Command" , new SessionStateCmdletEntry ( "Get-Command" , typeof ( GetCommandCommand ) , helpFile ) } ,
{ "Get-Help" , new SessionStateCmdletEntry ( "Get-Help" , typeof ( GetHelpCommand ) , helpFile ) } ,
{ "Get-History" , new SessionStateCmdletEntry ( "Get-History" , typeof ( GetHistoryCommand ) , helpFile ) } ,
{ "Get-Job" , new SessionStateCmdletEntry ( "Get-Job" , typeof ( GetJobCommand ) , helpFile ) } ,
{ "Get-Module" , new SessionStateCmdletEntry ( "Get-Module" , typeof ( GetModuleCommand ) , helpFile ) } ,
{ "Get-PSHostProcessInfo" , new SessionStateCmdletEntry ( "Get-PSHostProcessInfo" , typeof ( GetPSHostProcessInfoCommand ) , helpFile ) } ,
{ "Get-PSSession" , new SessionStateCmdletEntry ( "Get-PSSession" , typeof ( GetPSSessionCommand ) , helpFile ) } ,
{ "Get-PSSessionCapability" , new SessionStateCmdletEntry ( "Get-PSSessionCapability" , typeof ( GetPSSessionCapabilityCommand ) , helpFile ) } ,
{ "Get-PSSessionConfiguration" , new SessionStateCmdletEntry ( "Get-PSSessionConfiguration" , typeof ( GetPSSessionConfigurationCommand ) , helpFile ) } ,
{ "Import-Module" , new SessionStateCmdletEntry ( "Import-Module" , typeof ( ImportModuleCommand ) , helpFile ) } ,
{ "Invoke-Command" , new SessionStateCmdletEntry ( "Invoke-Command" , typeof ( InvokeCommandCommand ) , helpFile ) } ,
{ "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 ) } ,
2016-04-28 22:41:25 +02:00
{ "New-PSRoleCapabilityFile" , new SessionStateCmdletEntry ( "New-PSRoleCapabilityFile" , typeof ( NewPSRoleCapabilityFileCommand ) , helpFile ) } ,
2016-03-30 23:20:52 +02:00
{ "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 ) } ,
2016-04-28 22:41:25 +02:00
{ "New-PSTransportOption" , new SessionStateCmdletEntry ( "New-PSTransportOption" , typeof ( NewPSTransportOptionCommand ) , helpFile ) } ,
2016-03-30 23:20:52 +02:00
{ "Out-Default" , new SessionStateCmdletEntry ( "Out-Default" , typeof ( OutDefaultCommand ) , helpFile ) } ,
{ "Out-Host" , new SessionStateCmdletEntry ( "Out-Host" , typeof ( OutHostCommand ) , helpFile ) } ,
{ "Out-Null" , new SessionStateCmdletEntry ( "Out-Null" , typeof ( OutNullCommand ) , helpFile ) } ,
{ "Receive-Job" , new SessionStateCmdletEntry ( "Receive-Job" , typeof ( ReceiveJobCommand ) , helpFile ) } ,
{ "Receive-PSSession" , new SessionStateCmdletEntry ( "Receive-PSSession" , typeof ( ReceivePSSessionCommand ) , helpFile ) } ,
{ "Register-ArgumentCompleter" , new SessionStateCmdletEntry ( "Register-ArgumentCompleter" , typeof ( RegisterArgumentCompleterCommand ) , helpFile ) } ,
{ "Register-PSSessionConfiguration" , new SessionStateCmdletEntry ( "Register-PSSessionConfiguration" , typeof ( RegisterPSSessionConfigurationCommand ) , helpFile ) } ,
{ "Remove-Job" , new SessionStateCmdletEntry ( "Remove-Job" , typeof ( RemoveJobCommand ) , helpFile ) } ,
{ "Remove-Module" , new SessionStateCmdletEntry ( "Remove-Module" , typeof ( RemoveModuleCommand ) , helpFile ) } ,
{ "Remove-PSSession" , new SessionStateCmdletEntry ( "Remove-PSSession" , typeof ( RemovePSSessionCommand ) , helpFile ) } ,
{ "Save-Help" , new SessionStateCmdletEntry ( "Save-Help" , typeof ( SaveHelpCommand ) , helpFile ) } ,
{ "Set-PSDebug" , new SessionStateCmdletEntry ( "Set-PSDebug" , typeof ( SetPSDebugCommand ) , helpFile ) } ,
{ "Set-PSSessionConfiguration" , new SessionStateCmdletEntry ( "Set-PSSessionConfiguration" , typeof ( SetPSSessionConfigurationCommand ) , helpFile ) } ,
{ "Set-StrictMode" , new SessionStateCmdletEntry ( "Set-StrictMode" , typeof ( SetStrictModeCommand ) , helpFile ) } ,
{ "Start-Job" , new SessionStateCmdletEntry ( "Start-Job" , typeof ( StartJobCommand ) , helpFile ) } ,
{ "Stop-Job" , new SessionStateCmdletEntry ( "Stop-Job" , typeof ( StopJobCommand ) , helpFile ) } ,
{ "Test-ModuleManifest" , new SessionStateCmdletEntry ( "Test-ModuleManifest" , typeof ( TestModuleManifestCommand ) , helpFile ) } ,
{ "Test-PSSessionConfigurationFile" , new SessionStateCmdletEntry ( "Test-PSSessionConfigurationFile" , typeof ( TestPSSessionConfigurationFileCommand ) , helpFile ) } ,
{ "Unregister-PSSessionConfiguration" , new SessionStateCmdletEntry ( "Unregister-PSSessionConfiguration" , typeof ( UnregisterPSSessionConfigurationCommand ) , helpFile ) } ,
{ "Update-Help" , new SessionStateCmdletEntry ( "Update-Help" , typeof ( UpdateHelpCommand ) , helpFile ) } ,
{ "Wait-Job" , new SessionStateCmdletEntry ( "Wait-Job" , typeof ( WaitJobCommand ) , helpFile ) } ,
{ "Where-Object" , new SessionStateCmdletEntry ( "Where-Object" , typeof ( WhereObjectCommand ) , helpFile ) } ,
#if ! CORECLR
{ "Add-PSSnapin" , new SessionStateCmdletEntry ( "Add-PSSnapin" , typeof ( AddPSSnapinCommand ) , helpFile ) } ,
{ "Disable-PSRemoting" , new SessionStateCmdletEntry ( "Disable-PSRemoting" , typeof ( DisablePSRemotingCommand ) , helpFile ) } ,
{ "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 ) } ,
{ "Remove-PSSnapin" , new SessionStateCmdletEntry ( "Remove-PSSnapin" , typeof ( RemovePSSnapinCommand ) , helpFile ) } ,
{ "Resume-Job" , new SessionStateCmdletEntry ( "Resume-Job" , typeof ( ResumeJobCommand ) , helpFile ) } ,
{ "Suspend-Job" , new SessionStateCmdletEntry ( "Suspend-Job" , typeof ( SuspendJobCommand ) , helpFile ) } ,
#endif
// Not exported, but are added via reflection so added here as well, though maybe they shouldn't be
{ "Out-LineOutput" , new SessionStateCmdletEntry ( "Out-LineOutput" , typeof ( OutLineOutputCommand ) , helpFile ) } ,
{ "Format-Default" , new SessionStateCmdletEntry ( "Format-Default" , typeof ( FormatDefaultCommand ) , helpFile ) } ,
} ;
foreach ( var val in cmdlets . Values )
{
val . SetPSSnapIn ( psSnapInInfo ) ;
}
providers = new Dictionary < string , SessionStateProviderEntry > ( StringComparer . OrdinalIgnoreCase )
{
{ "Registry" , new SessionStateProviderEntry ( "Registry" , typeof ( RegistryProvider ) , helpFile ) } ,
{ "Alias" , new SessionStateProviderEntry ( "Alias" , typeof ( AliasProvider ) , helpFile ) } ,
{ "Environment" , new SessionStateProviderEntry ( "Environment" , typeof ( EnvironmentProvider ) , helpFile ) } ,
{ "FileSystem" , new SessionStateProviderEntry ( "FileSystem" , typeof ( FileSystemProvider ) , helpFile ) } ,
{ "Function" , new SessionStateProviderEntry ( "Function" , typeof ( FunctionProvider ) , helpFile ) } ,
{ "Variable" , new SessionStateProviderEntry ( "Variable" , typeof ( VariableProvider ) , helpFile ) } ,
} ;
foreach ( var val in providers . Values )
{
val . SetPSSnapIn ( psSnapInInfo ) ;
}
}
private static void ExecuteModuleInitializer ( Assembly assembly , Type [ ] assemblyTypes , bool isModuleLoad )
{
for ( int i = 0 ; i < assemblyTypes . Length ; i + + )
{
Type type = assemblyTypes [ i ] ;
TypeInfo typeInfo = type . GetTypeInfo ( ) ;
if ( ! ( typeInfo . IsPublic | | typeInfo . IsNestedPublic ) | | typeInfo . IsAbstract ) { continue ; }
if ( isModuleLoad & & typeof ( IModuleAssemblyInitializer ) . IsAssignableFrom ( type ) & & type ! = typeof ( IModuleAssemblyInitializer ) )
{
2016-07-29 22:02:49 +02:00
s_assembliesWithModuleInitializerCache . Value [ assembly ] = true ;
2016-04-28 22:41:25 +02:00
IModuleAssemblyInitializer moduleInitializer = ( IModuleAssemblyInitializer ) Activator . CreateInstance ( type , true ) ;
2016-03-30 23:20:52 +02:00
moduleInitializer . OnImport ( ) ;
}
}
}
internal static Type [ ] GetAssemblyTypes ( Assembly assembly , string name )
{
Type [ ] assemblyTypes = null ;
try
{
var exportedTypes = assembly . ExportedTypes ;
assemblyTypes = exportedTypes as Type [ ] ? ? exportedTypes . ToArray ( ) ;
}
catch ( ReflectionTypeLoadException e )
{
string message ;
message = e . Message ;
message + = "\nLoader Exceptions: \n" ;
if ( e . LoaderExceptions ! = null )
{
foreach ( Exception exception in e . LoaderExceptions )
{
message + = "\n" + exception . Message ;
}
}
2016-07-29 22:02:49 +02:00
s_PSSnapInTracer . TraceError ( message ) ;
2016-03-30 23:20:52 +02:00
throw new PSSnapInException ( name , message ) ;
}
return assemblyTypes ;
}
// cmdletCache holds the list of cmdlets along with its aliases per each assembly.
2016-08-03 04:00:50 +02:00
private static Lazy < ConcurrentDictionary < Assembly , Dictionary < string , Tuple < SessionStateCmdletEntry , List < SessionStateAliasEntry > > > > > s_cmdletCache =
2016-03-30 23:20:52 +02:00
new Lazy < ConcurrentDictionary < Assembly , Dictionary < string , Tuple < SessionStateCmdletEntry , List < SessionStateAliasEntry > > > > > ( ) ;
2016-08-03 04:00:50 +02:00
private static Lazy < ConcurrentDictionary < Assembly , Dictionary < string , SessionStateProviderEntry > > > s_providerCache =
2016-03-30 23:20:52 +02:00
new Lazy < ConcurrentDictionary < Assembly , Dictionary < string , SessionStateProviderEntry > > > ( ) ;
// Using a ConcurrentDictionary for this so that we can avoid having a private lock variable. We use only the keys for checking.
2016-07-29 22:02:49 +02:00
private static Lazy < ConcurrentDictionary < Assembly , bool > > s_assembliesWithModuleInitializerCache = new Lazy < ConcurrentDictionary < Assembly , bool > > ( ) ;
2016-03-30 23:20:52 +02:00
2016-08-03 04:00:50 +02:00
private static string GetCmdletName ( CmdletAttribute cmdletAttribute )
2016-03-30 23:20:52 +02:00
{
string verb = cmdletAttribute . VerbName ;
string noun = cmdletAttribute . NounName ;
return verb + "-" + noun ;
}
2016-08-03 04:00:50 +02:00
private static string GetProviderName ( CmdletProviderAttribute providerAttribute )
2016-03-30 23:20:52 +02:00
{
return providerAttribute . ProviderName ;
}
2016-08-03 04:00:50 +02:00
private static bool IsCmdletClass ( Type type )
2016-03-30 23:20:52 +02:00
{
if ( type = = null )
return false ;
return type . IsSubclassOf ( typeof ( System . Management . Automation . Cmdlet ) ) ;
}
2016-08-03 04:00:50 +02:00
private static bool IsProviderClass ( Type type )
2016-03-30 23:20:52 +02:00
{
if ( type = = null )
return false ;
return type . IsSubclassOf ( typeof ( System . Management . Automation . Provider . CmdletProvider ) ) ;
}
2016-08-03 04:00:50 +02:00
internal static bool IsModuleAssemblyInitializerClass ( Type type )
2016-03-30 23:20:52 +02:00
{
if ( type = = null )
{
return false ;
}
return type . IsSubclassOf ( typeof ( System . Management . Automation . IModuleAssemblyInitializer ) ) ;
}
2016-08-03 04:00:50 +02:00
private static bool HasDefaultConstructor ( Type type )
2016-03-30 23:20:52 +02:00
{
return ! ( type . GetConstructor ( PSTypeExtensions . EmptyTypes ) = = null ) ;
}
2016-08-03 04:00:50 +02:00
private static string GetHelpFile ( string assemblyPath )
2016-03-30 23:20:52 +02:00
{
return Path . GetFileName ( assemblyPath ) + StringLiterals . HelpFileExtension ;
}
2016-08-03 04:00:50 +02:00
private static PSTraceSource s_PSSnapInTracer = PSTraceSource . GetTracer ( "PSSnapInLoadUnload" , "Loading and unloading mshsnapins" , false ) ;
2016-03-30 23:20:52 +02:00
}
// Guid is {15d4c170-2f29-5689-a0e2-d95b0c7b4ea0}
[EventSource(Name = "Microsoft-PowerShell-Runspaces")]
internal class RunspaceEventSource : EventSource
{
internal static RunspaceEventSource Log = new RunspaceEventSource ( ) ;
public void OpenRunspaceStart ( ) { WriteEvent ( 1 ) ; }
public void OpenRunspaceStop ( ) { WriteEvent ( 2 ) ; }
public void LoadAssembliesStart ( ) { WriteEvent ( 3 ) ; }
public void LoadAssembliesStop ( ) { WriteEvent ( 4 ) ; }
public void UpdateFormatTableStart ( ) { WriteEvent ( 5 ) ; }
public void UpdateFormatTableStop ( ) { WriteEvent ( 6 ) ; }
public void UpdateTypeTableStart ( ) { WriteEvent ( 7 ) ; }
public void UpdateTypeTableStop ( ) { WriteEvent ( 8 ) ; }
public void LoadProvidersStart ( ) { WriteEvent ( 9 ) ; }
public void LoadProvidersStop ( ) { WriteEvent ( 10 ) ; }
public void LoadCommandsStart ( ) { WriteEvent ( 11 ) ; }
public void LoadCommandsStop ( ) { WriteEvent ( 12 ) ; }
public void LoadVariablesStart ( ) { WriteEvent ( 13 ) ; }
public void LoadVariablesStop ( ) { WriteEvent ( 14 ) ; }
public void LoadEnvironmentVariablesStart ( ) { WriteEvent ( 15 ) ; }
public void LoadEnvironmentVariablesStop ( ) { WriteEvent ( 16 ) ; }
public void LoadAssemblyStart ( string Name , string FileName ) { WriteEvent ( 17 , Name , FileName ) ; }
public void LoadAssemblyStop ( string Name , string FileName ) { WriteEvent ( 18 , Name , FileName ) ; }
public void ProcessFormatFileStart ( string FileName ) { WriteEvent ( 19 , FileName ) ; }
public void ProcessFormatFileStop ( string FileName ) { WriteEvent ( 20 , FileName ) ; }
public void ProcessTypeFileStart ( string FileName ) { WriteEvent ( 21 , FileName ) ; }
public void ProcessTypeFileStop ( string FileName ) { WriteEvent ( 22 , FileName ) ; }
public void LoadProviderStart ( string Name ) { WriteEvent ( 23 , Name ) ; }
public void LoadProviderStop ( string Name ) { WriteEvent ( 24 , Name ) ; }
public void LoadCommandStart ( string Name ) { WriteEvent ( 25 , Name ) ; }
public void LoadCommandStop ( string Name ) { WriteEvent ( 26 , Name ) ; }
}
}