diff --git a/reference/docs-conceptual/developer/cmdlet/advisory-development-guidelines.md b/reference/docs-conceptual/developer/cmdlet/advisory-development-guidelines.md index e4e76675fab9..c61330b7f541 100644 --- a/reference/docs-conceptual/developer/cmdlet/advisory-development-guidelines.md +++ b/reference/docs-conceptual/developer/cmdlet/advisory-development-guidelines.md @@ -1,6 +1,6 @@ --- description: Advisory Development Guidelines -ms.date: 10/05/2021 +ms.date: 05/22/2025 title: Advisory Development Guidelines --- # Advisory Development Guidelines @@ -19,10 +19,10 @@ guidelines. Because Windows PowerShell works directly with Microsoft .NET Framework objects, a .NET Framework object is often available that exactly matches the type the user needs to perform a particular operation. `InputObject` is the standard name for a parameter that takes such an object as input. -For example, the sample `Stop-Proc` cmdlet in the [StopProc Tutorial](./stopproc-tutorial.md) -defines an `InputObject` parameter of type Process that supports the input from the pipeline. The -user can get a set of process objects, manipulate them to select the exact objects to stop, and then -pass them to the `Stop-Proc` cmdlet directly. +For example, the sample `Stop-Proc` cmdlet in the [StopProc Tutorial][03] defines an `InputObject` +parameter of type Process that supports the input from the pipeline. The user can get a set of +process objects, manipulate them to select the exact objects to stop, and then pass them to the +`Stop-Proc` cmdlet directly. ### Support the Force Parameter (AD02) @@ -30,20 +30,19 @@ Occasionally, a cmdlet needs to protect the user from performing a requested ope cmdlet should support a **Force** parameter to allow the user to override that protection if the user has permissions to perform the operation. -For example, the [Remove-Item](/powershell/module/microsoft.powershell.management/remove-item) -cmdlet does not normally remove a read-only file. However, this cmdlet supports a **Force** -parameter so a user can force removal of a read-only file. If the user already has permission to -modify the read-only attribute, and the user removes the file, use of the **Force** parameter -simplifies the operation. However, if the user does not have permission to remove the file, the -**Force** parameter has no effect. +For example, the [Remove-Item][18] cmdlet doesn't normally remove a read-only file. However, this +cmdlet supports a **Force** parameter so a user can force removal of a read-only file. If the user +already has permission to modify the read-only attribute, and the user removes the file, use of the +**Force** parameter simplifies the operation. However, if the user doesn't have permission to remove +the file, the **Force** parameter has no effect. ### Handle Credentials Through Windows PowerShell (AD03) A cmdlet should define a `Credential` parameter to represent credentials. This parameter must be of -type [System.Management.Automation.PSCredential](/dotnet/api/System.Management.Automation.PSCredential) -and must be defined using a Credential attribute declaration. This support automatically prompts the -user for the user name, for the password, or for both when a full credential is not supplied -directly. For more information about the Credential attribute, see [Credential Attribute Declaration](./credential-attribute-declaration.md). +type [System.Management.Automation.PSCredential][15] and must be defined using a Credential +attribute declaration. This support automatically prompts the user for the user name, for the +password, or for both when a full credential isn't supplied directly. For more information about the +Credential attribute, see [Credential Attribute Declaration][01]. ### Support Encoding Parameters (AD04) @@ -53,12 +52,13 @@ encoded in the binary form. ### Test Cmdlets Should Return a Boolean (AD05) -Cmdlets that perform tests against their resources should return a [System.Boolean](/dotnet/api/System.Boolean) -type to the pipeline so that they can be used in conditional expressions. +Cmdlets that perform tests against their resources should return a [System.Boolean][06] type to the +pipeline so that they can be used in conditional expressions. ## Code Guidelines -The following guidelines should be considered when writing cmdlet code. When you find a guideline that applies to your situation, be sure to look at the Design guidelines for similar guidelines. +The following guidelines should be considered when writing cmdlet code. When you find a guideline +that applies to your situation, be sure to look at the Design guidelines for similar guidelines. ### Follow Cmdlet Class Naming Conventions (AC01) @@ -68,100 +68,116 @@ developers using Windows PowerShell because cmdlets are public types. #### Define a Cmdlet in the Correct Namespace -You normally define the class for a cmdlet in a .NET Framework namespace that appends ".Commands" to +You normally define the class for a cmdlet in a .NET Framework namespace that appends `.Commands` to the namespace that represents the product in which the cmdlet runs. For example, cmdlets that are included with Windows PowerShell are defined in the `Microsoft.PowerShell.Commands` namespace. #### Name the Cmdlet Class to Match the Cmdlet Name When you name the .NET Framework class that implements a cmdlet, name the class -"*\**\**\*", where you replace the *\* and *\* placeholders with -the verb and noun used for the cmdlet name. For example, the [Get-Process](/powershell/module/Microsoft.PowerShell.Management/Get-Process) -cmdlet is implemented by a class called `GetProcessCommand`. +`Command`, where you replace the `` and `` placeholders with the verb and +noun used for the cmdlet name. For example, the [Get-Process][17] cmdlet is implemented by a class +called `GetProcessCommand`. ### If No Pipeline Input Override the BeginProcessing Method (AC02) -If your cmdlet does not accept input from the pipeline, processing should be implemented in the [System.Management.Automation.Cmdlet.BeginProcessing](/dotnet/api/System.Management.Automation.Cmdlet.BeginProcessing) -method. Use of this method allows Windows PowerShell to maintain ordering between cmdlets. The first -cmdlet in the pipeline always returns its objects before the remaining cmdlets in the pipeline get a -chance to start their processing. +If your cmdlet doesn't accept input from the pipeline, processing should be implemented in the +[System.Management.Automation.Cmdlet.BeginProcessing][09] method. Use of this method allows Windows +PowerShell to maintain ordering between cmdlets. The first cmdlet in the pipeline always returns its +objects before the remaining cmdlets in the pipeline get a chance to start their processing. ### To Handle Stop Requests Override the StopProcessing Method (AC03) -Override the [System.Management.Automation.Cmdlet.StopProcessing](/dotnet/api/System.Management.Automation.Cmdlet.StopProcessing) -method so that your cmdlet can handle stop signal. Some cmdlets take a long time to complete their -operation, and they let a long time pass between calls to the Windows PowerShell runtime, such as -when the cmdlet blocks the thread in long-running RPC calls. This includes cmdlets that make calls -to the [System.Management.Automation.Cmdlet.WriteObject](/dotnet/api/System.Management.Automation.Cmdlet.WriteObject) -method, to the [System.Management.Automation.Cmdlet.WriteError](/dotnet/api/System.Management.Automation.Cmdlet.WriteError) -method, and to other feedback mechanisms that may take a long time to complete. For these cases the -user might need to send a stop signal to these cmdlets. +Override the [System.Management.Automation.Cmdlet.StopProcessing][12] method so that your cmdlet can +handle stop signal. Some cmdlets take a long time to complete their operation, and they let a long +time pass between calls to the Windows PowerShell runtime, such as when the cmdlet blocks the thread +in long-running RPC calls. This includes cmdlets that make calls to the +[System.Management.Automation.Cmdlet.WriteObject][14] method, to the +[System.Management.Automation.Cmdlet.WriteError][13] method, and to other feedback mechanisms that +may take a long time to complete. For these cases the user might need to send a stop signal to these +cmdlets. ### Implement the IDisposable Interface (AC04) -If your cmdlet has objects that are not disposed of (written to the pipeline) by the [System.Management.Automation.Cmdlet.ProcessRecord](/dotnet/api/System.Management.Automation.Cmdlet.ProcessRecord) -method, your cmdlet might require additional object disposal. For example, if your cmdlet opens a -file handle in its [System.Management.Automation.Cmdlet.BeginProcessing](/dotnet/api/System.Management.Automation.Cmdlet.BeginProcessing) -method and keeps the handle open for use by the [System.Management.Automation.Cmdlet.ProcessRecord](/dotnet/api/System.Management.Automation.Cmdlet.ProcessRecord) -method, this handle has to be closed at the end of processing. - -The Windows PowerShell runtime does not always call the [System.Management.Automation.Cmdlet.EndProcessing](/dotnet/api/System.Management.Automation.Cmdlet.EndProcessing) -method. For example, the [System.Management.Automation.Cmdlet.EndProcessing](/dotnet/api/System.Management.Automation.Cmdlet.EndProcessing) -method might not be called if the cmdlet is canceled midway through its operation or if a -terminating error occurs in any part of the cmdlet. Therefore, the .NET Framework class for a cmdlet -that requires object cleanup should implement the complete [System.IDisposable](/dotnet/api/System.IDisposable) -interface pattern, including the finalizer, so that the Windows PowerShell runtime can call both the [System.Management.Automation.Cmdlet.EndProcessing](/dotnet/api/System.Management.Automation.Cmdlet.EndProcessing) -and [System.IDisposable.Dispose*](/dotnet/api/System.IDisposable.Dispose) methods at the end of -processing. +If your cmdlet has objects that aren't disposed of (written to the pipeline) by the +[System.Management.Automation.Cmdlet.ProcessRecord][11] method, your cmdlet might require additional +object disposal. For example, if your cmdlet opens a file handle in its +[System.Management.Automation.Cmdlet.BeginProcessing][09] method and keeps the handle open for use +by the [System.Management.Automation.Cmdlet.ProcessRecord][11] method, this handle has to be closed +at the end of processing. + +The Windows PowerShell runtime doesn't always call the +[System.Management.Automation.Cmdlet.EndProcessing][10] method. For example, the +[System.Management.Automation.Cmdlet.EndProcessing][10] method might not be called if the cmdlet is +canceled midway through its operation or if a terminating error occurs in any part of the cmdlet. +Therefore, the .NET Framework class for a cmdlet that requires object cleanup should implement the +complete [System.IDisposable][07] interface pattern, including the finalizer, so that the Windows +PowerShell runtime can call both the [System.Management.Automation.Cmdlet.EndProcessing][10] and +[System.IDisposable.Dispose*][08] methods at the end of processing. ### Use Serialization-friendly Parameter Types (AC05) -To support running your cmdlet on remote computers, use types that can be easily serialized on the -client computer and then rehydrated on the server computer. The follow types are -serialization-friendly. +To support running your cmdlet on remote computers, use types that can be serialized on the client +computer and then rehydrated on the server computer. The follow types are serialization-friendly. Primitive types: - Byte, SByte, Decimal, Single, Double, Int16, Int32, Int64, Uint16, UInt32, and UInt64. - - Boolean, Guid, Byte[], TimeSpan, DateTime, Uri, and Version. - - Char, String, XmlDocument. Built-in rehydratable types: - PSPrimitiveDictionary - - SwitchParameter - - PSListModifier - - PSCredential - - IPAddress, MailAddress - - CultureInfo - - X509Certificate2, X500DistinguishedName - - DirectorySecurity, FileSecurity, RegistrySecurity Other types: - SecureString - - Containers (lists and dictionaries of the above type) ### Use SecureString for Sensitive Data (AC06) -When handling sensitive data always use the [System.Security.Securestring](/dotnet/api/System.Security.SecureString) -data type. This could include pipeline input to parameters, as well as returning sensitive data to -the pipeline. +When handling sensitive data always use the [System.Security.SecureString][16] data type. This could +include pipeline input to parameters, as well as returning sensitive data to the pipeline. -## See Also - -[Required Development Guidelines](./required-development-guidelines.md) +While .NET recommends against using **SecureString** for new development, PowerShell continues to +support the **SecureString** class for backward compatibility. Using a **SecureString** is still +more secure than using a plain text string. PowerShell still relies on the **SecureString** type to +avoid accidentally exposing the contents to the console or in logs. Use **SecureString** carefully, +because it can be easily converted to a plain text string. For a full discussion about using +**SecureString**, see the [System.Security.SecureString class][01] documentation. -[Strongly Encouraged Development Guidelines](./strongly-encouraged-development-guidelines.md) +## See Also -[Writing a Windows PowerShell Cmdlet](./writing-a-windows-powershell-cmdlet.md) +[Required Development Guidelines][02] + +[Strongly Encouraged Development Guidelines][04] + +[Writing a Windows PowerShell Cmdlet][05] + + +[01]: ./credential-attribute-declaration.md +[02]: ./required-development-guidelines.md +[03]: ./stopproc-tutorial.md +[04]: ./strongly-encouraged-development-guidelines.md +[05]: ./writing-a-windows-powershell-cmdlet.md +[06]: xref:System.Boolean +[07]: xref:System.IDisposable +[08]: xref:System.IDisposable.Dispose +[09]: xref:System.Management.Automation.Cmdlet.BeginProcessing +[10]: xref:System.Management.Automation.Cmdlet.EndProcessing +[11]: xref:System.Management.Automation.Cmdlet.ProcessRecord +[12]: xref:System.Management.Automation.Cmdlet.StopProcessing +[13]: xref:System.Management.Automation.Cmdlet.WriteError%2A +[14]: xref:System.Management.Automation.Cmdlet.WriteObject%2A +[15]: xref:System.Management.Automation.PSCredential +[16]: xref:System.Security.SecureString +[17]: xref:Microsoft.PowerShell.Management.Get-Process +[18]: xref:Microsoft.PowerShell.Management.Remove-Item diff --git a/reference/docs-conceptual/security/security-features.md b/reference/docs-conceptual/security/security-features.md index 91488e42babf..550a28eaa55d 100644 --- a/reference/docs-conceptual/security/security-features.md +++ b/reference/docs-conceptual/security/security-features.md @@ -1,6 +1,6 @@ --- description: PowerShell has several features designed to improve the security of your scripting environment. -ms.date: 09/19/2024 +ms.date: 05/22/2025 title: PowerShell security features --- # PowerShell security features @@ -14,7 +14,7 @@ PowerShell loads configuration files and runs scripts. This feature helps preven malicious scripts. You can use a Group Policy setting to set execution policies for computers and users. Execution policies only apply to the Windows platform. -For more information see [about_Execution_Policies][02]. +For more information, see [about_Execution_Policies][02]. ## Use of the SecureString class @@ -25,16 +25,17 @@ using passwords and rely on other means to authenticate, such as certificates or authentication. PowerShell continues to support the **SecureString** class for backward compatibility. Using a -**SecureString** is still more secure than using a plain text string. By default, PowerShell doesn't -show the unprotected value of a **SecureString** object. However, **SecureString** can be easily -converted to a plain text string. For a full discussion about using **SecureString**, see the -[System.Security.SecureString class][01] documentation. +**SecureString** is still more secure than using a plain text string. PowerShell still relies on the +**SecureString** type to avoid accidentally exposing the contents to the console or in logs. Use +**SecureString** carefully, because it can be easily converted to a plain text string. For a full +discussion about using **SecureString**, see the [System.Security.SecureString class][01] +documentation. ## Module and script block logging Module Logging allows you to enable logging for selected PowerShell modules. This setting is effective in all sessions on the computer. PowerShell records pipeline execution events for the -specified modules in the Windows PowerShell log in Event Viewer. +specified modules in the Windows PowerShell event log. Script Block Logging enables logging for the processing of commands, script blocks, functions, and scripts - whether invoked interactively, or through automation. PowerShell logs this information to @@ -52,8 +53,8 @@ The Windows Antimalware Scan Interface (AMSI) is an API that allows applications an antimalware scanner, such as Windows Defender, to scan for malicious payloads. Beginning with PowerShell 5.1, PowerShell running on Windows 10 (and higher) passes all script blocks to AMSI. -PowerShell 7.3 extends the data that's sent to AMSI for inspection. It now includes all invocations -of .NET method members. +PowerShell 7.3 extends the data it sends to AMSI for inspection. It now includes all .NET method +invocations. For more information about AMSI, see [How AMSI helps][09].