How Windows PowerShell Works
This section describes how Microsoft® Windows® PowerShell operates. Topics in this section include:
Overview of Windows PowerShell Operation
Windows PowerShell Path Concepts
Overview of Windows PowerShell Operation
Windows PowerShell furnishes an operating environment for commands that include cmdlets, functions, filters, scripts, aliases, and executables (applications). The main command type used in this environment is the cmdlet, with certain cmdlets made available only through Windows PowerShell providers that allow access to stored data.
Windows PowerShell operates within a hosting application (the default is powershell.exe) that exposes a command line to the user, and uses a host interface to communicate with the commands invoked by the command line. The hosting application can be a console application, a Windows application, or a Web application. In most cases, the hosting application uses its Main function to interact with the Windows PowerShell runtime through the internal host interface; however, a hosting application can optionally support its own custom host by implementing the PSHost class along with one or more related user interface classes. Together, these classes allow direct communication between the application and Windows PowerShell commands.
The Windows PowerShell runtime is the execution engine that provides the operating environment for Windows PowerShell. The data retrieved and written by the runtime is in the form of data objects that are compatible with the .NET Framework. For more information about how Windows PowerShell handles objects, see Windows PowerShell Object Concepts.
Invoked as a runspace, the Windows PowerShell runtime normally processes commands synchronously and delivers the results of processing to the hosting application, which then renders the results for the user. In this case, there is only the default interaction between the hosting application and the commands in a runspace.
As mentioned previously, Windows PowerShell also supports the execution scenario in which the hosting application implements its own custom host. In this case, the runspace is kept open and any number of commands can be run. The custom host can retrieve the results of processing either synchronously or asynchronously.
Creating a Runspace
The first thing that the hosting application must do in communicating with the Windows PowerShell runtime is to create a runspace, which is the abstraction of the Windows PowerShell runtime used to simplify a user session. To do this, the hosting application calls the CreateRunspace method of the RunspaceFactory class. The runspace itself is represented by a Runspace object.
In addition, Windows PowerShell provides the RunspaceConfiguration class to define the configuration of the runspace. Configuration information includes data about commands and Windows PowerShell providers that the hosting application supports, and startup scripts for the runspace. User scripts are not reflected in the runspace configuration.
When a runspace is created, a corresponding session is automatically opened, with its state represented by a SessionState object. Session state data includes information about Windows PowerShell paths, Windows PowerShell drives, Windows PowerShell providers, plus cmdlets and other commands that are active during the session.
Working with Windows PowerShell Providers
Windows PowerShell uses the Windows PowerShell provider infrastructure in the Windows PowerShell runtime to manage the Windows PowerShell providers. It normally starts the installed Windows PowerShell providers when it initializes the runspace and the corresponding session state, which tracks the providers in a global dictionary. The session state uses a path search mechanism to find all the *.cmdletprovider files reflected in the PSCOMMANDPATH and PATH environment variables.
At Windows PowerShell startup, the Windows PowerShell provider infrastructure passes to the session state the Windows PowerShell paths to desired .cmdletprovider files, with optional provider details. When it obtains required information from the session state, the Windows PowerShell provider infrastructure calls the Start method on each provider for any necessary initialization. If there are any exceptions for a provider, it is not loaded and initialization of other providers continues. When the last call to Start returns, the Windows PowerShell provider infrastructure calls the InitializeDefaultDrives method for each provider that supports a drive. For each PSDriveInfo object that a provider returns, the infrastructure creates a new drive and then verifies the drive and adds private data with a call to NewDriveDynamicParameters. The verified drive is added to the global scope in the session state, and the provider is added to the provider dictionary.
When the Windows PowerShell provider infrastructure has invoked all providers for the session, it reserves the provider and drive information to be used in routing calls to and from the correct provider, along with references to the current working drive for each provider. The infrastructure uses a dictionary to maintain multiple directory stacks that push a reference to a drive and a copy of the current working directory when a Push-Location command is processed for a provider. The top item on the stack is popped in response to a Pop-Location command.
A particular provider is accessed only when the pipeline processor encounters a command that is supported by that provider, for example, the New-Item cmdlet supported by the ContainerCmdletProvider base class using its NewItem method. The Windows PowerShell provider infrastructure determines which provider to call based on the value of the Path parameter of the command being processed. When access to the provider is required, the first call is to a method that retrieves any dynamic parameters that correspond to the command. When the dynamic parameters are available, the next call can be made to the main method, which is NewItem for the container provider example.
Within Windows PowerShell, the Windows PowerShell runtime and commands interact with the Windows PowerShell providers using Windows PowerShell paths, as described in PSPath Concepts. Commands can access information about the providers or retrieve provider data using the Provider, Drive, Path, and InvokeProvider members of SessionState.
Opening the Runspace
When the hosting application has created a runspace, it must open the runspace for the type of session that is required. For a session using synchronous I/O, the application can call the Open method. If the application uses asynchronous I/O and must perform other operations while the runspace fulfills a read/write request, it can call the OpenAsync method. If calling OpenAsync, a hosting application defining a custom host will need to support an appropriate callback method to receive I/O notifications.
When the runspace is opened, the hosting application can manipulate the session by creating and invoking pipelines in the runspace, as described in Processing Commands. Several aspects of the runspace session can also be controlled by the user of the hosting application, through the use of variables. These variables represent user preferences and usually control the display of output by the hosting application.
The runspace allows the hosting application to manipulate the session with calls to the GetVariable and SetVariable methods of the SessionStateProxy object for the session. Be aware that this object does not represent a complete session state, but only exposes a few methods that allow the hosting application to easily set and get variable values. For more information about Windows PowerShell variables, see the Windows PowerShell Getting Started Guide. You can find out what variables are supported by using the Get-Help cmdlet for a particular variable group.
Creating the Pipeline
When the hosting application has accumulated a command sequence from the user, it must form the commands into one or more pipelines, each represented by a Pipeline object for the active runspace. Different applications use different criteria for determining when to create pipelines from the command sequence entered by the user. For example, Windows PowerShell.exe uses a command line that is terminated by a carriage return to indicate the end of a command sequence.
A command sequence can be made up of multiple nested pipelines, separated by semicolon (;) statement separators. Here's an example of such a sequence.
PS>pqr | bar; a | b
The Windows PowerShell runtime represents this sequence as one pipeline with two nested pipelines, pqr | bar and a | b.
As another example, a Microsoft Management Console (MMC) snap-in, such as Microsoft Exchange, has a set of prepared scripts that it will run in response to certain UI interaction. This type of hosting application parameterizes a script and creates a pipeline with that script to perform an action.
For the Windows PowerShell.exe hosting application, the Out-Host cmdlet is always the terminal command in the pipeline. Windows PowerShell uses this cmdlet, which produces no output, as a "sink" for the output of command processing. For an application that does not use a sink, the output from command processing is returned to the host as a result of the call to invoke the pipeline. For more information, see Starting the Pipeline.
To create its own pipeline, the hosting application calls either the CreatePipeline method or the CreateNestedPipeline method. The application calls CreatePipeline to form an empty pipeline or if it must create a pipeline and populate it with commands. If the application must create a pipeline for a runspace with its current pipeline executing, it must call CreateNestedPipeline.
The runspace has its parser go through the following steps when it receives a call to create either type of pipeline.
Create a pipeline processor.
Use command discovery to retrieve command processors for each of the commands.
Add command tokens to the pipeline processor, which gives each command one input stream, called InputPipe, and at least two outgoing streams, OutputPipe and ErrorOutputPipe.
Add the command tokens to the appropriate command processors.
Special classes, for example, CmdletInfo, are used to represent the information for the different command types that the user of the hosting application furnishes. The runspace session uses an AuthorizationManager object that is responsible for command authorization before the runspace can invoke a command. During its pipeline creation, the runspace will call ShouldRun with the information for each command and the command origin, to determine if the command can be part of the pipeline. For more about authorization in Windows PowerShell, see Authorization Concepts.
Starting the Pipeline
Now that its pipeline is set up, the hosting application must start its operation. If the application is using synchronous I/O, it calls the Invoke method, using the variant for either an empty pipeline or a populated one. For asynchronous I/O, the application can call InvokeAsync instead.
When the runspace receives the call to invoke the pipeline, the parser starts the pipeline processor. During command processing, this processor will move .NET objects from the output streams of one command to the input stream of the next downstream command. For more information, see Processing Commands.
With the pipeline invoked, the pipeline processor can proceed to execute the pipelined commands. The following figure illustrates the main operational flow of command processing.
Binding Parameters that Take Command Line Input
During its first binding phase, the pipeline processor binds values to the parameters specified by the user as command line input. The pipeline processor triggers the command processor for each of these commands in turn to perform the initial binding. For each command, the first binding phase is broken up into these steps.
Bind named parameters.
Bind positional parameters.
Bind common parameters.
Bind parameters to support calls to ShouldProcess.
Bind dynamic parameters, first the named ones, and then the positional ones.
During the first binding phase, the pipeline processor uses the metadata for the parameters, the type definitions of the extended type system (ETS), and type coercion of parameter values. Type coercion is the process of making a parameter value of a particular type become a value of another type.
If the pipeline processor finishes its processing and finds any unbound parameters for the commands taking command line input, the pipeline fails and processing ceases. If all parameters for these commands are bound successfully, the pipeline processor continues as described in Starting Command Processing.
Starting Command Processing
The pipeline processor can start command processing once all parameters that take command line input have been bound to their values. To do this, the processor calls the BeginProcessing method for the first pipelined command. This method does nothing if the command is using the default implementation. If the command implements an override for the method, however, the method performs preprocessing and initialization. Upon return from the first call to BeginProcessing, the pipeline processor calls the method in the rest of the commands in the pipeline until all commands have been able to do any preprocessing required. If a command appears in the pipeline more than once, each occurrence is treated as a separate command.
Binding Parameters that Take Pipeline Input
With all commands activated, the pipeline processor must now go through another binding phase. In this operation, the processor must bind values to the parameters for each command that accepts pipeline input. The second binding phase uses these steps.
Bind command-defined pipeline parameters
Bind dynamic pipeline parameters
When this binding phase is complete, the pipeline processor can proceed to process record, as described in Processing Records.
With all binding completed, the pipeline processor can process records. Starting with the first command in the pipeline, the processor goes through the following record processing steps.
Determine if all mandatory parameter values are available, and fail the record if they are not.
Verify that there is a single parameter set defined, and fail the record if there is not.
Call the ProcessRecord method in the downstream command. This method does nothing if the command is using the default implementation. If the command implements an override for the method, however, the method processes the record.
Upon return from ProcessRecord, set any pipeline parameters to original values.
Check for more pipeline objects.
If there are more objects, bind the parameters as described in Binding Parameters that Take Pipeline Input.
Repeat the steps above until all records have been processed for the commands in the pipeline.
Ending Command Processing
When all records have been processed, the pipeline processor tells each successive command processor to call the EndProcessing method in the associated command. This method does nothing if the command is using the default implementation. If the command implements an override for the method, however, the method performs postprocessing as required.
For the Windows PowerShell.exe application, the output of command processing is presented to the Out-Host cmdlet at the end of the pipeline. For an application that does not provide an output sink, the output is written by way Invoke or InvokeAsync. For more information, see Starting the Pipeline.
Disposing of the Pipeline
At the end of command processing, the hosting application must call the Dispose method for the Pipeline object.
Closing the Runspace
The hosting application can close the Runspace object when it is finished with command processing. The application calls the Close method if it is using synchronous I/O, or the CloseAsync method if using asynchronous I/O.
Windows PowerShell Path Concepts
A Windows PowerShell path is designated with the string "PSPath". It is the common mechanism for uniquely identifying an item obtainable through a virtual drive supported by a Windows PowerShell provider. Designation of this drive allows the use of stored data, such as data in the Registry, in a consistent way. Each provider has a current working virtual drive, and a current location is maintained for each virtual drive. The current working directory is always relative to a virtual drive.
The Windows PowerShell runtime and commands use Windows PowerShell paths dealing only with the PSPath identifier and the Windows PowerShell provider base classes and interfaces. Details of path interpretation are left to the particular Windows PowerShell provider.
The following table lists the basic types of Windows PowerShell paths.
The current working directory can be indicated by a drive-qualified or a provider-qualified path.
|Windows PowerShell Path Type||Definition|
This path (also known as "absolute path") starts with a drive name followed by a colon (:), for example, mydrive:\abc\bar. Windows PowerShell uses the drive name to determine the provider associated with the path, and to determine the root of the drive and path. If the current location is a drive-qualified path, the drive-qualified path for a child item can start with ".." to indicate the parent location. An example is ..\abc\bar. The root of the current drive can be indicated with a backslash (\), for example, \abc\bar.
This path starts with a provider name, followed by two colons (::), for example, FileSystem::\\uncshare\abc\bar for the filesystem provider. The Windows PowerShell runtime uses this path to call a provider explicitly. The runtime treats the information following the "::" as a provider-internal path.
This path starts with "\\" or "//" and is passed directly to the provider for the current location. Wildcard expansion occurs but the path syntax is not modified, which allows for UNC path support in the filesystem provider furnished with Windows PowerShell. The path syntax can also be used for remote paths in other providers. For example, the registry provider can use \\server\regkeypath to provide remote access.
If the current location is not for the desired data, for example, the filesystem, and the user wants to access a UNC network share, a provider-qualified path must be used.
This path is understood only by a specific provider and the Windows PowerShell runtime. It is indicated after the "::" in a provider-qualified Windows PowerShell path.
The Windows PowerShell provider infrastructure of the Windows PowerShell runtime supports wildcard expansion on any path supplied by a provider. A resolved path has a resolved target, and uses no wildcard characters in its representation. An unresolved path contains wildcard characters, and therefore indicates an incompletely resolved target. The class used for wildcard pattern matching is WildcardPattern.
Representing Paths in PowerShell
For a runspace session, the SessionState object manages access to the currently loaded Windows PowerShell providers. Calling the Path property retrieves a PathIntrinsics object that gives path data for all available providers. The caller can obtain the home directory for one of the providers by accessing the corresponding ProviderInfo object.
Supporting a Path in a Cmdlet
A cmdlet supports Windows PowerShell path input by defining a Path parameter, with an alias of PSPath.
If the data that the cmdlet reads/writes has to be a file, the cmdlet should use the Path property of the SessionState object to translate the Windows PowerShell paths into paths that the filesystem recognizes. Translation uses calls to the GetUnresolvedProviderPathFromPSPath and GetResolvedProviderPathFromPSPath methods.
If the cmdlet reads/writes data that is just a set of strings, the cmdlet should use the Content member of the provider class. This information is obtained from the InvokeProvider property of the CmdletProvider class.
Setting a Path
A Windows PowerShell path can be set for a session with a call to the SetLocation method.
Getting the Current Working Directory for a Windows PowerShell Provider
The CurrentProviderLocation method allows retrieval of the current working directory for a Windows PowerShell provider.
A Windows PowerShell path can begin with a tilde (~) to indicate the home directory for the provider, for example, ~\abc\bar.
Getting a Resolved Provider Path from a Windows PowerShell Path
The PSCmdlet class exposes the GetResolvedProviderPathFromPSPath method to obtain the fully-qualified path for a Windows PowerShell provider. If a relative path is passed to GetResolvedProviderPathFromPSPath, the method does the work of expanding the path, including "..\", "~\", and ".\" notations, to the fully-qualified provider path.
Getting an Unresolved Provider Path from a Windows PowerShell path
The PSCmdlet class provides the GetUnresolvedProviderPathFromPSPath method to obtain the unresolved path for a Windows PowerShell provider.
The Windows PowerShell authorization (security) model controls the authorization of sessions, applications, and all types of commands to operate in the shell. This section provides a brief overview of authorization concepts.
Windows PowerShell Authorization Manager
The Windows PowerShell runtime uses the AuthorizationManager class to define an authorization manager that allows execution for a command. Windows PowerShell provides an implementation of this class that uses Internet origin and Authenticode signatures to form the basis of its authorization decision. You can replace the default authorization manager with a custom manager module that handles the authorization request in a specialized way.
The Windows PowerShell authorization model does not allow authentication to be customized. Authentication is performed outside the scope of the authorization manager.
Windows PowerShell Execution Policies
Windows PowerShell supports certain execution policies that define the restrictions under which files are loaded for configuration and execution. The following table lists the execution policies. By default, Windows PowerShell is configured to use the Restricted execution policy.
For more information about working with the Windows PowerShell execution policies, enter the following on the Windows PowerShell command line: PS>get-help about-signing.
This execution policy requires all files to be signed, including scripts that you write. Using this policy, Windows PowerShell operates as described below.
The AllSigned execution policy exposes the user to the risk of running possibly malicious scripts, although signed, after confirming that the publisher is trusted.
For more information about signing a file, enter the following on the Windows PowerShell command line:
This execution policy requires signing for all files downloaded from communication applications, such as Microsoft Outlook, Internet Explorer, Outlook Express, and Windows Messenger. Scripts created on the current system do not require digital signatures. Using this policy, Windows PowerShell operates as described below.
The RemoteSigned execution policy exposes the user, without prompting, to the risk of running malicious scripts not downloaded from a communication application.
This execution policy is the default, and provides the highest level of security. Using this policy, Windows PowerShell operates as described below.
This execution policy requires no signing for files downloaded from communication applications. Using this policy, Windows PowerShell operates as described below.
The Unrestricted execution policy exposes the user to the risk of running malicious unsigned scripts downloaded from communication applications.
To change an execution policy, the user can use the Set-ItemProperty cmdlet on the Windows PowerShell command line. Windows PowerShell recognizes changes to execution policy immediately. Entry of the cmdlet requires administrator privileges.
The following is an example that sets the execution policy to RemoteSigned. For more information about cmdlet entry in Windows PowerShell, see Using the Windows PowerShell Shell and Language.
set-itemproperty ' HKLM:\SOFTWARE\Microsoft\PS\Microsoft.Management.Automation.ps ' -property ExecutionPolicy -value RemoteSigned
Windows PowerShell also allows the user to change the execution policy using the Registry editor. The Registry key is as shown above, and the user merely changes the setting of ExecutionPolicy as desired.