Assigning to iss.ExecutionPolicy
only ever controls the execution policy for the current process.
Do not assign a Microsoft.PowerShell.ExecutionPolicyScope
value, as it is an unrelated enumeration that defines the execution-policy scope, relevant only to the Set-ExecutionPolicy
and Get-ExecutionPolicy
cmdlets. The numeric values of this unrelated enumeration just so happen to overlap with the appropriate [Microsoft.PowerShell.ExecutionPolicy]
enumeration values, so that policy scope CurrentUser
maps onto policy RemoteSigned
(value 0x1
).
- In effect, your second
iss.ExecutionPolicy = ...
assignment overrides the first one and sets the process-scope execution policy to RemoteSigned
.
- The process-scope execution policy, i.e. for the current process only, is the only one you can set via an initial session state; see the next section for how to change policies for persistent scopes.
Therefore, iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
alone is enough to invoke *.ps1
files in the session at hand - remove the second iss.ExecutionPolicy = ...
assignment.
If you want to modify the execution policy persistently, you must use .AddCommand('Set-ExecutionPolicy')
with the appropriate arguments and invoke that command. Caveat:
Changing the persistent current-user configuration also takes effect for regular PowerShell sessions (interactive ones / CLI calls) in the respective PowerShell edition.
By contrast, if you change the persistent machine configuration - which requires running with elevation (as admin):
- With the Windows PowerShell SDK, the change also takes effect for regular PowerShell sessions.
- With the PowerShell (Core) SDK, it only takes effect for the SDK project at hand.[1]
See this answer for sample code.
Caveat:
If the current user's / machine's execution policy is controlled via GPOs (Group Policy Objects), you fundamentally cannot override it programmatically (except via GPO changes).
To check if a GPO-based policy is in effect:
- Run
Get-ExecutionPolicy -List
to list policies defined for each available scope, in descending order of precedence.
- If either the
MachinePolicy
or the UserPolicy
scope have a value other than Undefined
, then a GPO policy is in effect (run Get-ExecutionPolicy
without arguments to see the effective policy for the current session).
Limited workaround for when a GPO-based policy prevents script-file execution:
Assuming all of the following; script file refers to *.ps1
files:
- Your script file calls no other script files.
- It (directly or indirectly) loads no modules that on import happen to call script files.
- Your script file doesn't rely on knowing its own location (directory) or name on disk.
You can load your script file's content into a string and pass that string to the SDK's .AddScript()
method, as the following simplified example shows:
using (var ps = PowerShell.Create()) {
var results =
ps.AddScript(File.ReadAllText(path + "\\" + fileName))
.AddParameters(commandParameters)
.Invoke();
}
[1] Windows PowerShell stores the execution policies in the registry, which both regular sessions and the SDK consult. By contrast, PowerShell (Core) stores them in powershell.config.json
files, and in the case of the machine policy alongside the PowerShell executable (DLL). Since SDK projects have their own executable, its attendant JSON file is not seen by the executable of a regular PowerShell (Core) installation.