MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4#region Using directives5 6using System;7// System.Management.Automation is the namespace which contains the types and8// methods pertaining to the Microsoft Command Shell9using System.Management.Automation;10using System.Management.Automation.Internal;11using System.Management.Automation.Tracing;12#endregion13 14namespace Microsoft.PowerShell.Commands15{16 /// <summary>17 /// Defines the implementation of the 'Get-ExecutionPolicy' cmdlet.18 /// This cmdlet gets the effective execution policy of the shell.19 ///20 /// In priority-order (highest priority first,) these come from:21 /// - Machine-wide Group Policy22 /// - Current-user Group Policy23 /// - Current session preference24 /// - Current user machine preference25 /// - Local machine preference.26 /// </summary>27 [Cmdlet(VerbsCommon.Get, "ExecutionPolicy", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096594")]28 [OutputType(typeof(ExecutionPolicy))]29 public class GetExecutionPolicyCommand : PSCmdlet30 {31 /// <summary>32 /// Gets or sets the scope of the execution policy.33 /// </summary>34 [Parameter(Position = 0, Mandatory = false, ValueFromPipelineByPropertyName = true)]35 public ExecutionPolicyScope Scope36 {37 get { return _executionPolicyScope; }38 39 set { _executionPolicyScope = value; _scopeSpecified = true; }40 }41 42 private ExecutionPolicyScope _executionPolicyScope = ExecutionPolicyScope.LocalMachine;43 private bool _scopeSpecified = false;44 45 /// <summary>46 /// Gets or sets the List parameter, which lists all scopes and their execution47 /// policies.48 /// </summary>49 [Parameter(Mandatory = false)]50 public SwitchParameter List51 {52 get { return _list; }53 54 set { _list = value; }55 }56 57 private bool _list;58 59 /// <summary>60 /// Outputs the execution policy.61 /// </summary>62 protected override void BeginProcessing()63 {64 if (_list && _scopeSpecified)65 {66 string message = ExecutionPolicyCommands.ListAndScopeSpecified;67 68 ErrorRecord errorRecord = new(69 new InvalidOperationException(),70 "ListAndScopeSpecified",71 ErrorCategory.InvalidOperation,72 targetObject: null);73 74 errorRecord.ErrorDetails = new ErrorDetails(message);75 ThrowTerminatingError(errorRecord);76 77 return;78 }79 80 string shellId = base.Context.ShellID;81 82 if (_list)83 {84 foreach (ExecutionPolicyScope scope in SecuritySupport.ExecutionPolicyScopePreferences)85 {86 PSObject outputObject = new();87 88 ExecutionPolicy policy = SecuritySupport.GetExecutionPolicy(shellId, scope);89 PSNoteProperty inputNote = new("Scope", scope);90 outputObject.Properties.Add(inputNote);91 inputNote = new PSNoteProperty(92 "ExecutionPolicy", policy);93 outputObject.Properties.Add(inputNote);94 95 WriteObject(outputObject);96 }97 }98 else if (_scopeSpecified)99 {100 WriteObject(SecuritySupport.GetExecutionPolicy(shellId, _executionPolicyScope));101 }102 else103 {104 WriteObject(SecuritySupport.GetExecutionPolicy(shellId));105 }106 }107 }108 109 /// <summary>110 /// Defines the implementation of the 'Set-ExecutionPolicy' cmdlet.111 /// This cmdlet sets the local preference for the execution policy of the112 /// shell.113 ///114 /// The execution policy may be overridden by settings in Group Policy.115 /// If the Group Policy setting overrides the desired behaviour, the Cmdlet116 /// generates a terminating error.117 /// </summary>118 [Cmdlet(VerbsCommon.Set, "ExecutionPolicy", SupportsShouldProcess = true, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096612")]119 public class SetExecutionPolicyCommand : PSCmdlet120 {121 /// <summary>122 /// Gets or sets the execution policy that the user requests.123 /// </summary>124 [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)]125 public ExecutionPolicy ExecutionPolicy126 {127 get { return _executionPolicy; }128 129 set { _executionPolicy = value; }130 }131 132 private ExecutionPolicy _executionPolicy;133 134 /// <summary>135 /// Gets or sets the scope of the execution policy.136 /// </summary>137 [Parameter(Position = 1, Mandatory = false, ValueFromPipelineByPropertyName = true)]138 public ExecutionPolicyScope Scope139 {140 get { return _executionPolicyScope; }141 142 set { _executionPolicyScope = value; }143 }144 145 private ExecutionPolicyScope _executionPolicyScope = ExecutionPolicyScope.LocalMachine;146 147 /// <summary>148 /// Specifies whether to force the execution policy change.149 /// </summary>150 /// <value></value>151 [Parameter]152 public SwitchParameter Force153 {154 get155 {156 return _force;157 }158 159 set160 {161 _force = value;162 }163 }164 165 private SwitchParameter _force;166 167 /// <summary>168 /// Sets the execution policy (validation).169 /// </summary>170 protected override void BeginProcessing()171 {172 // Verify they've specified a valid scope173 if ((_executionPolicyScope == ExecutionPolicyScope.UserPolicy) ||174 (_executionPolicyScope == ExecutionPolicyScope.MachinePolicy))175 {176 string message = ExecutionPolicyCommands.CantSetGroupPolicy;177 178 ErrorRecord errorRecord = new(179 new InvalidOperationException(),180 "CantSetGroupPolicy",181 ErrorCategory.InvalidOperation,182 targetObject: null);183 184 errorRecord.ErrorDetails = new ErrorDetails(message);185 ThrowTerminatingError(errorRecord);186 187 return;188 }189 }190 191 /// <summary>192 /// Set the desired execution policy.193 /// </summary>194 protected override void ProcessRecord()195 {196 string shellId = base.Context.ShellID;197 string executionPolicy = SecuritySupport.GetExecutionPolicy(ExecutionPolicy);198 199 if (ShouldProcessPolicyChange(executionPolicy))200 {201 try202 {203 SecuritySupport.SetExecutionPolicy(_executionPolicyScope, ExecutionPolicy, shellId);204 }205 catch (UnauthorizedAccessException exception)206 {207 OnAccessDeniedError(exception);208 }209 catch (System.Security.SecurityException exception)210 {211 OnAccessDeniedError(exception);212 }213 214 // Ensure it is now the effective execution policy215 if (ExecutionPolicy != ExecutionPolicy.Undefined)216 {217 string effectiveExecutionPolicy = SecuritySupport.GetExecutionPolicy(shellId).ToString();218 if (!string.Equals(effectiveExecutionPolicy, executionPolicy, StringComparison.OrdinalIgnoreCase))219 {220 string message = StringUtil.Format(ExecutionPolicyCommands.ExecutionPolicyOverridden, effectiveExecutionPolicy);221 string recommendedAction = ExecutionPolicyCommands.ExecutionPolicyOverriddenRecommendedAction;222 223 ErrorRecord errorRecord = new(224 new System.Security.SecurityException(),225 "ExecutionPolicyOverride",226 ErrorCategory.PermissionDenied,227 targetObject: null);228 229 errorRecord.ErrorDetails = new ErrorDetails(message);230 errorRecord.ErrorDetails.RecommendedAction = recommendedAction;231 ThrowTerminatingError(errorRecord);232 }233 }234 235 PSEtwLog.LogSettingsEvent(MshLog.GetLogContext(Context, MyInvocation),236 EtwLoggingStrings.ExecutionPolicyName, executionPolicy, null);237 }238 }239 240 // Determine if we should process this policy change241#if CORECLR // Seems that we cannot find if the cmdlet is executed interactive or through a script on CoreCLR242 private bool ShouldProcessPolicyChange(string localPreference)243 {244 return ShouldProcess(localPreference);245 }246#else247 private bool ShouldProcessPolicyChange(string localPreference)248 {249 if (ShouldProcess(localPreference))250 {251 // See if we're being invoked directly at the252 // command line. In that case, give a warning.253 if (!Force)254 {255 // We don't give this warning if we're in a script, or256 // if we don't have a window handle257 // (i.e.: PowerShell -command Set-ExecutionPolicy Unrestricted)258 if (IsProcessInteractive())259 {260 string query = ExecutionPolicyCommands.SetExecutionPolicyQuery;261 string caption = ExecutionPolicyCommands.SetExecutionPolicyCaption;262 263 try264 {265 bool yesToAllNoToAllDefault = false;266 if (!ShouldContinue(query, caption, true, ref yesToAllNoToAllDefault, ref yesToAllNoToAllDefault))267 {268 return false;269 }270 }271 catch (InvalidOperationException)272 {273 // Host is non-interactive. This should274 // return false, but must return true due275 // to backward compatibility.276 return true;277 }278 catch (System.Management.Automation.Host.HostException)279 {280 // Host doesn't implement ShouldContinue. This should281 // return false, but must return true due282 // to backward compatibility.283 return true;284 }285 }286 }287 288 return true;289 }290 291 return false;292 }293 294 private bool IsProcessInteractive()295 {296 // CommandOrigin != Runspace means it is in a script297 if (MyInvocation.CommandOrigin != CommandOrigin.Runspace)298 return false;299 300 // If we don't own the window handle, we've been invoked301 // from another process that just calls "PowerShell -Command"302 if (System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle == IntPtr.Zero)303 return false;304 305 // If the window has been idle for less than a second,306 // they're probably still calling "PowerShell -Command"307 // but from Start-Process, or the StartProcess API308 try309 {310 System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();311 TimeSpan timeSinceStart = DateTime.Now - currentProcess.StartTime;312 TimeSpan idleTime = timeSinceStart - currentProcess.TotalProcessorTime;313 314 if (idleTime.TotalSeconds > 1)315 return true;316 }317 catch (System.ComponentModel.Win32Exception)318 {319 // Don't have access to the properties320 return false;321 }322 323 return false;324 }325#endif326 327 // Throw terminating error when the access to the registry is denied328 private void OnAccessDeniedError(Exception exception)329 {330 string message = StringUtil.Format(ExecutionPolicyCommands.SetExecutionPolicyAccessDeniedError, exception.Message);331 ErrorRecord errorRecord = new(332 exception,333 exception.GetType().FullName,334 ErrorCategory.PermissionDenied,335 targetObject: null);336 337 errorRecord.ErrorDetails = new ErrorDetails(message);338 ThrowTerminatingError(errorRecord);339 }340 }341}342 