diff --git a/reference/7.6/CimCmdlets/CimCmdlets.md b/reference/7.6/CimCmdlets/CimCmdlets.md new file mode 100644 index 000000000000..4fd9f0673f62 --- /dev/null +++ b/reference/7.6/CimCmdlets/CimCmdlets.md @@ -0,0 +1,76 @@ +--- +Download Help Link: https://aka.ms/powershell75-help +Help Version: 7.6.0.0 +Locale: en-US +Module Guid: fb6cc51d-c096-4b38-b78d-0fed6277096a +Module Name: CimCmdlets +ms.date: 02/20/2019 +schema: 2.0.0 +title: CimCmdlets Module +--- +# CimCmdlets Module + +## Description + +Contains cmdlets that interact with Common Information Model (CIM) Servers like the Windows +Management Instrumentation (WMI) service. + +This module is only available on the Windows platform. + +## CimCmdlets Cmdlets + +### [Export-BinaryMiLog](Export-BinaryMiLog.md) + +Creates a binary encoded representation of an object or objects and stores it in a file. + +### [Get-CimAssociatedInstance](Get-CimAssociatedInstance.md) + +Retrieves the CIM instances that are connected to a specific CIM instance by an association. + +### [Get-CimClass](Get-CimClass.md) + +Gets a list of CIM classes in a specific namespace. + +### [Get-CimInstance](Get-CimInstance.md) + +Gets the CIM instances of a class from a CIM server. + +### [Get-CimSession](Get-CimSession.md) + +Gets the CIM session objects from the current session. + +### [Import-BinaryMiLog](Import-BinaryMiLog.md) + +Used to re-create the saved objects based on the contents of an export file. + +### [Invoke-CimMethod](Invoke-CimMethod.md) + +Invokes a method of a CIM class. + +### [New-CimInstance](New-CimInstance.md) + +Creates a CIM instance. + +### [New-CimSession](New-CimSession.md) + +Creates a CIM session. + +### [New-CimSessionOption](New-CimSessionOption.md) + +Specifies advanced options for the `New-CimSession` cmdlet. + +### [Register-CimIndicationEvent](Register-CimIndicationEvent.md) + +Subscribes to indications using a filter expression or a query expression. + +### [Remove-CimInstance](Remove-CimInstance.md) + +Removes a CIM instance from a computer. + +### [Remove-CimSession](Remove-CimSession.md) + +Removes one or more CIM sessions. + +### [Set-CimInstance](Set-CimInstance.md) + +Modifies a CIM instance on a CIM server by calling the **ModifyInstance** method of the CIM class. diff --git a/reference/7.6/CimCmdlets/Get-CimAssociatedInstance.md b/reference/7.6/CimCmdlets/Get-CimAssociatedInstance.md new file mode 100644 index 000000000000..dac584057ba6 --- /dev/null +++ b/reference/7.6/CimCmdlets/Get-CimAssociatedInstance.md @@ -0,0 +1,337 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 05/31/2024 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/get-cimassociatedinstance?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Get-CimAssociatedInstance +--- + +# Get-CimAssociatedInstance + +## SYNOPSIS +Retrieves the CIM instances that are connected to a specific CIM instance by an association. + +## SYNTAX + +### ComputerSet (Default) + +``` +Get-CimAssociatedInstance [[-Association] ] [-ResultClassName ] + [-InputObject] [-Namespace ] [-OperationTimeoutSec ] + [-ResourceUri ] [-ComputerName ] [-KeyOnly] [] +``` + +### SessionSet + +``` +Get-CimAssociatedInstance [[-Association] ] [-ResultClassName ] + [-InputObject] [-Namespace ] [-OperationTimeoutSec ] + [-ResourceUri ] -CimSession [-KeyOnly] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `Get-CimAssociatedInstance` cmdlet retrieves the CIM instances connected to a specific CIM +instance, called the source instance, by an association. + +In an association, each CIM instance has a named role and the same CIM instance can participate in +an association in different roles. + +If the **InputObject** parameter isn't specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet works on local Windows Management Instrumentation (WMI) using a Component Object Model + (COM) session. +- If either the **ComputerName** parameter or the **CimSession** parameter is specified, then this + cmdlet works against the CIM server specified by either the **ComputerName** parameter or the + **CimSession** parameter. + +## EXAMPLES + +### Example 1: Get all the associated instances of a specific instance + +```powershell +$disk = Get-CimInstance -ClassName Win32_LogicalDisk -KeyOnly +Get-CimAssociatedInstance -InputObject $disk[1] +``` + +This set of commands retrieves the instances of the class named Win32_LogicalDisk and stores the +information in a variable named `$disk` using the `Get-CimInstance` cmdlet. The first logical disk +instance in the variable is then used as the input object for the `Get-CimAssociatedInstance` cmdlet +to get all the associated CIM instances of the specified CIM instance. + +### Example 2: Get all the associated instances of a specific type + +```powershell +$disk = Get-CimInstance -ClassName Win32_LogicalDisk -KeyOnly +Get-CimAssociatedInstance -InputObject $disk[1] -ResultClass Win32_DiskPartition +``` + +This set of commands retrieves all the instances of the **Win32_LogicalDisk** class and stores them +in a variable named `$disk`. The first logical disk instance in the variable is then used as the +input object for the `Get-CimAssociatedInstance` cmdlet to get all the associated instances that are +associated through the specified association class **Win32_DiskPartition**. + +### Example 3: Get all the associated instances through qualifier of a specific class + +This set of commands retrieves the services that depend on the **Winmgmt** service and stores them +in a variable named `$s`. `Get-CimAssociatedInstance` gets the associated instances of the retrieved +association class. + +```powershell +$s = Get-CimInstance -Query "Select * from Win32_Service where name like 'Winmgmt'" +Get-CimAssociatedInstance -InputObject $s -Association Win32_DependentService +``` + +```Output +ProcessId Name StartMode State Status ExitCode +--------- ---- --------- ----- ------ -------- +1716 RpcSs Auto Running OK 0 +9964 CcmExec Auto Running OK 0 +0 HgClientService Manual Stopped OK 1077 +0 smstsmgr Manual Stopped OK 1077 +3396 vmms Auto Running OK 0 +``` + +## PARAMETERS + +### -Association + +Specifies the name of the association class. If you don't specify this parameter, the cmdlet returns +all existing association objects of any type. + +For example, if class A is associated with class B through two associations, AB1 and AB2, then this +parameter can be used to specify the type of association, either AB1 or AB2. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -CimSession + +Runs the command using the specified CIM session. Enter a variable that contains the CIM session, or +a command that creates or gets the CIM session, such as `New-CimSession` or `Get-CimSession`. For +more information, see [about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: SessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer on which you want to run the CIM operation. You can specify a +fully qualified domain name (FQDN) or a NetBIOS name. + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WsMan protocol. + +If you don't specify this parameter, the cmdlet performs the operation on the local computer using +Component Object Model (COM). + +If multiple operations are being performed on the same computer, connecting using a CIM session +gives better performance. + +```yaml +Type: System.String[] +Parameter Sets: ComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -InputObject + +Specifies the input to this cmdlet. You can use this parameter, or you can pipe the input to this +cmdlet. + +The **InputObject** parameter doesn't enumerate over collections. If a collection is passed, an +error is thrown. When working with collections, pipe the input to enumerate the values. + +```yaml +Type: Microsoft.Management.Infrastructure.CimInstance +Parameter Sets: (All) +Aliases: CimInstance + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -KeyOnly + +Returns objects with only key properties populated. This reduces the amount of data that's +transferred over the network. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace for the CIM operation. The default namespace is root/cimv2. + +> [!NOTE] +> You can use tab completion to browse the list of namespaces, because PowerShell gets a list of +> namespaces from the local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value of this parameter is 0, which means that the cmdlet uses the default timeout value for the +server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter aren't recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ResourceUri + +Specifies the resource uniform resource identifier (URI) of the resource class or instance. The URI +is used to identify a specific type of resource, such as disks or processes, on a computer. + +A URI consists of a prefix and a path to a resource. For example: + +- `http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk` +- `http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings` + +By default, if you don't specify this parameter, the DMTF standard resource URI +`http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/` is used and the class name is appended to it. + +**ResourceURI** can only be used with CIM sessions created using the WSMan protocol, or when +specifying the **ComputerName** parameter, which creates a CIM session using WSMan. If you specify +this parameter without specifying the **ComputerName** parameter, or if you specify a CIM session +created using DCOM protocol, you get an error, because the DCOM protocol doesn't support the +**ResourceURI** parameter. + +If both the **ResourceUri** parameter and the **Filter** parameter are specified, the **Filter** +parameter is ignored. + +```yaml +Type: System.Uri +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ResultClassName + +Specifies the class name of the associated instances. A CIM instance can be associated with one or +more CIM instances. All associated CIM instances are returned if you don't specify the result class +name. + +By default, the value of this parameter is null, and all associated CIM instances are returned. + +You can filter the association results to match a specific class name. Filtering happens on the +server. If this parameter isn't specified, `Get-CIMAssociatedInstance` returns all existing +associations. For example, if class A is associated with classes B, C and D, then this parameter can +be used to restrict the output to a specific type (B, C or D). + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.CimInstance + +This cmdlet returns a CIM instance object. + +## NOTES + +PowerShell includes the following aliases for `Get-CimAssociatedInstance`: + +- Windows: + - `gcai` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-CimClass](get-cimclass.md) + +[Get-CimInstance](get-ciminstance.md) diff --git a/reference/7.6/CimCmdlets/Get-CimClass.md b/reference/7.6/CimCmdlets/Get-CimClass.md new file mode 100644 index 000000000000..3994f76e5a0c --- /dev/null +++ b/reference/7.6/CimCmdlets/Get-CimClass.md @@ -0,0 +1,321 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 09/11/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/get-cimclass?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Get-CimClass +--- + +# Get-CimClass + +## SYNOPSIS +Gets a list of CIM classes in a specific namespace. + +## SYNTAX + +### ComputerSet (Default) + +``` +Get-CimClass [[-ClassName] ] [[-Namespace] ] [-Amended] + [-OperationTimeoutSec ] [-ComputerName ] [-MethodName ] + [-PropertyName ] [-QualifierName ] [] +``` + +### SessionSet + +``` +Get-CimClass [[-ClassName] ] [[-Namespace] ] -CimSession [-Amended] + [-OperationTimeoutSec ] [-MethodName ] [-PropertyName ] + [-QualifierName ] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `Get-CimClass` cmdlet retrieves a list of CIM classes in a specific namespace. If there is no +class name supplied, then the cmdlet returns all the classes in the namespace. Unlike a CIM +instance, CIM classes do not contain the CIM session or computer name from which they are retrieved. + +## EXAMPLES + +### Example 1: Get all the class definitions + +This example gets all the class definitions under the namespace **root/cimv2**. + +```powershell +Get-CimClass +``` + +### Example 2: Get the classes with a specific name + +This example gets the classes that contain the word **disk** in their names. + +```powershell +Get-CimClass -ClassName *disk* +``` + +### Example 3: Get the classes with a specific method name + +This example gets the classes that start with the name **Win32** and have a method name that starts +with **Term**. + +```powershell +Get-CimClass -ClassName Win32* -MethodName Term* +``` + +### Example 4: Get the classes with a specific property name + +This example gets the classes that start with the name **Win32** and have a property named +**Handle**. + +```powershell +Get-CimClass -ClassName Win32* -PropertyName Handle +``` + +### Example 5: Get the classes with a specific qualifier name + +This example gets the classes that start with the name **Win32**, contain the word **Disk** in their +names and have the specified qualifier **Association**. + +```powershell +Get-CimClass -ClassName Win32*Disk* -QualifierName Association +``` + +### Example 6: Get the class definitions from a specific namespace + +This example gets the class definitions that contain the word **Net** in their names from the +specified namespace **root/standardCimv2**. + +```powershell +Get-CimClass -Namespace root/standardCimv2 -ClassName *Net* +``` + +### Example 7: Get the class definitions from a remote server + +This example gets the class definitions that contain the word **disk** in their names from the +specified remote servers **Server01** and **Server02**. + +```powershell +Get-CimClass -ClassName *disk* -ComputerName Server01, Server02 +``` + +### Example 8: Get the classes by using a CIM session + +```powershell +$s = New-CimSession -ComputerName Server01, Server02 +Get-CimClass -ClassName *disk* -CimSession $s +``` + +This set of commands creates a session with multiple computers and stores it into a variable `$s` +using the `New-CimSession` cmdlet, and then gets the classes using the `Get-CimClass` cmdlet. + +## PARAMETERS + +### -Amended + +Indicates that objects returned from the CIM query should contain amended information. Typically, +amended information is localizable information, such as object and property descriptions that are +attached to the CIM object. This is useful for translating numeric values to human-readable values. + +This parameter was added in PowerShell 7.3. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -CimSession + +Runs the cmdlet in a remote session or on a remote computer. Enter a computer name or a session +object, such as the output of a `New-CimSession` or `Get-CimSession` cmdlet. The default is the +current session on the local computer. + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: SessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ClassName + +Specifies the name of the CIM class for which to perform the operation. You can use tab completion +to browse the list of classes, because PowerShell gets a list of classes from the local WMI server +to provide a list of class names. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### -ComputerName + +Specifies the computer on which you want to run the CIM operation. You can specify a fully qualified +domain name (FQDN) a NetBIOS name, or an IP address. + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WsMan protocol. + +If you do not specify this parameter, the cmdlet performs the operation on the local computer using +Component Object Model (COM). + +If multiple operations are being performed on the same computer, using a CIM session gives better +performance. + +```yaml +Type: System.String[] +Parameter Sets: ComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -MethodName + +Finds the classes that have a method matching this name. You can use wildcard characters with this +parameter. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### -Namespace + +Specifies the namespace for CIM operation. The default namespace is **root/cimv2**. You can use tab +completion to browse the list of namespaces, because PowerShell gets a list of namespaces from the +local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value of this parameter is 0, which means that the cmdlet uses the default timeout value for the +server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -PropertyName + +Finds the classes which have a property matching this name. You can use wildcard characters with +this parameter. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### -QualifierName + +Filters the classes by class level qualifier name. You can use wildcard characters with this +parameter. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.CimClass + +This cmdlet returns a CIM class object. + +## NOTES + +PowerShell includes the following aliases for `Get-CimClass`: + +- Windows: + - `gcls` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[New-CimSession](New-CimSession.md) diff --git a/reference/7.6/CimCmdlets/Get-CimInstance.md b/reference/7.6/CimCmdlets/Get-CimInstance.md new file mode 100644 index 000000000000..26a2b8d78b3a --- /dev/null +++ b/reference/7.6/CimCmdlets/Get-CimInstance.md @@ -0,0 +1,540 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/get-ciminstance?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Get-CimInstance +--- + +# Get-CimInstance + +## SYNOPSIS +Gets the CIM instances of a class from a CIM server. + +## SYNTAX + +### ClassNameComputerSet (Default) + +``` +Get-CimInstance [-ClassName] [-ComputerName ] [-KeyOnly] [-Namespace ] + [-OperationTimeoutSec ] [-QueryDialect ] [-Shallow] [-Filter ] + [-Property ] [] +``` + +### ResourceUriSessionSet + +``` +Get-CimInstance -CimSession -ResourceUri [-KeyOnly] [-Namespace ] + [-OperationTimeoutSec ] [-Shallow] [-Filter ] [-Property ] + [] +``` + +### QuerySessionSet + +``` +Get-CimInstance -CimSession [-ResourceUri ] [-Namespace ] + [-OperationTimeoutSec ] -Query [-QueryDialect ] [-Shallow] + [] +``` + +### ClassNameSessionSet + +``` +Get-CimInstance -CimSession [-ClassName] [-KeyOnly] [-Namespace ] + [-OperationTimeoutSec ] [-QueryDialect ] [-Shallow] [-Filter ] + [-Property ] [] +``` + +### CimInstanceSessionSet + +``` +Get-CimInstance -CimSession [-ResourceUri ] [-OperationTimeoutSec ] + [-InputObject] [] +``` + +### CimInstanceComputerSet + +``` +Get-CimInstance [-ResourceUri ] [-ComputerName ] [-OperationTimeoutSec ] + [-InputObject] [] +``` + +### ResourceUriComputerSet + +``` +Get-CimInstance -ResourceUri [-ComputerName ] [-KeyOnly] [-Namespace ] + [-OperationTimeoutSec ] [-Shallow] [-Filter ] [-Property ] + [] +``` + +### QueryComputerSet + +``` +Get-CimInstance [-ResourceUri ] [-ComputerName ] [-Namespace ] + [-OperationTimeoutSec ] -Query [-QueryDialect ] [-Shallow] + [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `Get-CimInstance` cmdlet gets the CIM instances of a class from a CIM server. You can specify +either the class name or a query for this cmdlet. This cmdlet returns one or more CIM instance +objects representing a snapshot of the CIM instances present on the CIM server. + +If the **InputObject** parameter is not specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet works on local Windows Management Instrumentation (WMI) using a Component Object Model + (COM) session. +- If either the **ComputerName** parameter or the **CimSession** parameter is specified, then this + cmdlet works against the CIM server specified by either the **ComputerName** parameter or the + **CimSession** parameter. + +If the **InputObject** parameter is specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet uses the CIM session or computer name from the input object. +- If the either the **ComputerName** parameter or the **CimSession** parameter is specified, then + this cmdlet uses the either the CimSession parameter value or **ComputerName** parameter value. + +## EXAMPLES + +### Example 1: Get the CIM instances of a specified class + +This example retrieves the CIM instances of a class named **Win32_Process**. + +```powershell +Get-CimInstance -ClassName Win32_Process +``` + +### Example 2: Get a list of namespaces from a WMI server + +This example retrieves a list of namespaces under the **Root** namespace on a WMI server. + +```powershell +Get-CimInstance -Namespace root -ClassName __Namespace +``` + +### Example 3: Get instances of a class filtered by using a query + +This example retrieves all the CIM instances that start with the letter **P** of a class named +**Win32_Process** using the query specified by a **Query** parameter. + +```powershell +Get-CimInstance -Query "SELECT * from Win32_Process WHERE name LIKE 'P%'" +``` + +### Example 4: Get instances of a class filtered by using a class name and a filter expression + +This example retrieves all the CIM instances that start with the letter **P** of a class named +**Win32_Process** using the Filter parameter. + +```powershell +Get-CimInstance -ClassName Win32_Process -Filter "Name like 'P%'" +``` + +### Example 5: Get the CIM instances with only key properties filled in + +This example creates a new CIM instance in memory for a class named **Win32_Process** with +the key property `@{ "Handle"=0 }` and stores it in a variable named `$x`. The variable is passed as +a CIM instance to the `Get-CimInstance` cmdlet to get a particular instance. + +```powershell +$x = New-CimInstance -ClassName Win32_Process -Namespace root\cimv2 -Property @{ "Handle"=0 } -Key Handle -ClientOnly +Get-CimInstance -CimInstance $x +``` + +### Example 6: Retrieve CIM instances and reuse them + +This example gets the CIM instances of a class named **Win32_Process** and stores them in +the variables `$x` and `$y`. The variable `$x` is then formatted in a table containing only the +**Name** and **KernelModeTime** properties, the table set to **AutoSize**. + +```powershell +$x,$y = Get-CimInstance -ClassName Win32_Process +$x | Format-Table -Property Name,KernelModeTime -AutoSize +``` + +```Output +Name KernelModeTime +---- -------------- +System Idle Process 157238797968750 +``` + +### Example 7: Get CIM instances from remote computer + +This example retrieves the CIM instances of a class named **Win32_ComputerSystem** from the remote +computers named **Server01** and **Server02**. + +```powershell +Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName Server01,Server02 +``` + +### Example 8: Getting only the key properties, instead of all properties + +This example retrieves only the key properties, which reduces the size of the object and network +traffic. + +```powershell +$x = Get-CimInstance -Class Win32_Process -KeyOnly +$x | Invoke-CimMethod -MethodName GetOwner +``` + +### Example 9: Getting only a subset of properties, instead of all properties + +This example retrieves only a subset of properties, which reduces the size of the object and network +traffic. + +```powershell +Get-CimInstance -Class Win32_Process -Property Name,KernelModeTime +$x = Get-CimInstance -Class Win32_Process -Property Name,KernelModeTime +$x | Invoke-CimMethod -MethodName GetOwner +``` + +The instance retrieved with the **Property** parameter can be used to perform other CIM operations, +for example `Set-CimInstance` or `Invoke-CimMethod`. + +### Example 10: Get the CIM instance using CIM session + +This example creates a CIM session on the computers named **Server01** and **Server02** using the +`New-CimSession` cmdlet and stores the session information in a variable named `$s`. The contents of +the variable are then passed to `Get-CimInstance` by using the **CimSession** parameter, to get the +CIM instances of the class named **Win32_ComputerSystem**. + +```powershell +$s = New-CimSession -ComputerName Server01,Server02 +Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $s +``` + +## PARAMETERS + +### -CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or +a command that creates or gets the CIM session, such as the `New-CimSession` or `Get-CimSession` +cmdlets. For more information, see [about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: ResourceUriSessionSet, QuerySessionSet, ClassNameSessionSet, CimInstanceSessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ClassName + +Specifies the name of the CIM class for which to retrieve the CIM instances. You can use tab +completion to browse the list of classes, because PowerShell gets a list of classes from the local +WMI server to provide a list of class names. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies computer on which you want to run the CIM operation. You can specify a fully qualified +domain name (FQDN), a NetBIOS name, or an IP address. If you do not specify this parameter, the +cmdlet performs the operation on the local computer using Component Object Model (COM). + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WsMan protocol. + +If multiple operations are being performed on the same computer, connect using a CIM session for +better performance. + +```yaml +Type: System.String[] +Parameter Sets: ClassNameComputerSet, CimInstanceComputerSet, ResourceUriComputerSet, QueryComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Filter + +Specifies a where clause to use as a filter. Specify the clause in either the **WQL** or the **CQL** +query language. Do not include the `WHERE` keyword in the value of the parameter. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ResourceUriSessionSet, ClassNameSessionSet, ResourceUriComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -InputObject + +Specifies a CIM instance object to use as input. + +If you are already working with a CIM instance object, you can use this parameter to pass the CIM +instance object in order to get the latest snapshot from the CIM server. When you pass a CIM +instance object as an input, `Get-CimInstance` returns the object from server using a get CIM +operation, instead of an enumerate or query operation. Using a get CIM operation is more efficient +than retrieving all instances and then filtering them. + +The **InputObject** parameter doesn't enumerate over collections. If a collection is passed, an +error is thrown. When working with collections, pipe the input to enumerate the values. + +If the CIM class does not implement the get operation, then specifying the **InputObject** parameter +returns an error. + +```yaml +Type: Microsoft.Management.Infrastructure.CimInstance +Parameter Sets: CimInstanceSessionSet, CimInstanceComputerSet +Aliases: CimInstance + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -KeyOnly + +Indicates that only objects with key properties populated are returned. Specifying the **KeyOnly** +parameter reduces the amount of data transferred over the network. + +Use the **KeyOnly** parameter to return only a small portion of the object, which can be used for other +operations, such as the `Set-CimInstance` or `Get-CimAssociatedInstance` cmdlets. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: ClassNameComputerSet, ResourceUriSessionSet, ClassNameSessionSet, ResourceUriComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace of CIM class. + +The default namespace is **root/cimv2**. You can use tab completion to browse the list of +namespaces, because PowerShell gets a list of namespaces from the local WMI server to provide the +list of namespaces. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ResourceUriSessionSet, QuerySessionSet, ClassNameSessionSet, ResourceUriComputerSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value of this parameter is 0, which means that the cmdlet uses the default timeout value for the +server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Property + +Specifies a set of instance properties to retrieve. Use this parameter when you need to reduce the +size of the object returned, either in memory or over the network. The object returned also contains +the key properties even if you have not listed them using the **Property** parameter. Other +properties of the class are present but they are not populated. + +```yaml +Type: System.String[] +Parameter Sets: ClassNameComputerSet, ResourceUriSessionSet, ClassNameSessionSet, ResourceUriComputerSet +Aliases: SelectProperties + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Query + +Specifies a query to run on the CIM server. If the value specified contains double quotes `"`, +single quotes `'`, or a backslash `\`, you must escape those characters by prefixing them with the +backslash character. If the value specified uses the WQL **LIKE** operator, then you must escape +the following characters by enclosing them in square brackets `[]`: percent `%`, underscore `_`, +or opening square bracket `[`. + +You cannot use a metadata query to retrieve a list of classes or an event query. To retrieve a list +of classes, use the `Get-CimClass` cmdlet. To retrieve an event query, use the +`Register-CimIndicationEvent` cmdlet. + +You can specify the query dialect using the **QueryDialect** parameter. + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -QueryDialect + +Specifies the query language used for the Query parameter. The acceptable values for this parameter +are: **WQL** or **CQL**. The default value is **WQL**. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, QuerySessionSet, ClassNameSessionSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ResourceUri + +Specifies the resource uniform resource identifier (URI) of the resource class or instance. The URI +is used to identify a specific type of resource, such as disks or processes, on a computer. + +A URI consists of a prefix and a path to a resource. For example: + +- `http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk` +- `http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings` + +By default, if you do not specify this parameter, the DMTF standard resource URI +`http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/` is used and the class name is appended to it. + +**ResourceURI** can only be used with CIM sessions created using the WSMan protocol, or when +specifying the **ComputerName** parameter, which creates a CIM session using WSMan. If you specify +this parameter without specifying the **ComputerName** parameter, or if you specify a CIM session +created using DCOM protocol, you will get an error, because the DCOM protocol does not support the +**ResourceURI** parameter. + +If both the **ResourceUri** parameter and the **Filter** parameter are specified, the **Filter** +parameter is ignored. + +```yaml +Type: System.Uri +Parameter Sets: ResourceUriSessionSet, ResourceUriComputerSet, QuerySessionSet, QueryComputerSet, CimInstanceSessionSet, CimInstanceComputerSet +Aliases: + +Required: True (ResourceUriSessionSet, ResourceUriComputerSet), False (QuerySessionSet, QueryComputerSet, CimInstanceSessionSet, CimInstanceComputerSet) +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Shallow + +Indicates that the instances of a class are returned without including the instances of any child +classes. By default, the cmdlet returns the instances of a class and its child classes. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: ClassNameComputerSet, ResourceUriSessionSet, QuerySessionSet, ClassNameSessionSet, ResourceUriComputerSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### Microsoft.Management.Infrastructure.CimInstance + +You can pipe a CIM instance object to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.CimInstance + +This cmdlet returns one or more CIM instance objects representing a snapshot of the CIM instances on +the CIM server. + +## NOTES + +PowerShell includes the following aliases for `Get-CimInstance`: + +- Windows: + - `gcim` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Format-Table](../microsoft.powershell.utility/format-table.md) + +[Get-CimAssociatedInstance](Get-CimAssociatedInstance.md) + +[Get-CimClass](Get-CimClass.md) + +[Invoke-CimMethod](invoke-cimmethod.md) + +[New-CimInstance](New-CimInstance.md) + +[Register-CimIndicationEvent](Register-CimIndicationEvent.md) + +[Remove-CimInstance](remove-ciminstance.md) + +[Set-CimInstance](Set-CimInstance.md) diff --git a/reference/7.6/CimCmdlets/Get-CimSession.md b/reference/7.6/CimCmdlets/Get-CimSession.md new file mode 100644 index 000000000000..09be413b56ab --- /dev/null +++ b/reference/7.6/CimCmdlets/Get-CimSession.md @@ -0,0 +1,263 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/get-cimsession?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Get-CimSession +--- + +# Get-CimSession + +## SYNOPSIS +Gets the CIM session objects from the current session. + +## SYNTAX + +### ComputerNameSet (Default) + +``` +Get-CimSession [[-ComputerName] ] [] +``` + +### SessionIdSet + +``` +Get-CimSession [-Id] [] +``` + +### InstanceIdSet + +``` +Get-CimSession -InstanceId [] +``` + +### NameSet + +``` +Get-CimSession -Name [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +By default, the cmdlet gets all of the CIM sessions created in the current PowerShell session. You +can use the parameters of `Get-CimSession` to get the sessions that are for particular computers, or +you can identify sessions by their names or other identifiers. `Get-CimSession` does not get CIM +sessions that were created in other PowerShell sessions or that were created on other computers. + +For more information about CIM sessions, see [about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +## EXAMPLES + +### Example 1: Get CIM sessions from the current PowerShell session + +This example creates CIM sessions using [New-CimSession](New-CimSession.md), and then gets the CIM +sessions using `Get-CimSession`. + +```powershell +New-CimSession -ComputerName Server01,Server02 +Get-CimSession +``` + +```Output +Id : 1 +Name : CimSession1 +InstanceId : d1413bc3-162a-4cb8-9aec-4d2c61253d59 +ComputerName : Server01 +Protocol : WSMAN + +Id : 2 +Name : CimSession2 +InstanceId : c0095981-52c5-4e7f-a5bb-c4c680541710 +ComputerName : Server02 +Protocol : WSMAN +``` + +### Example 2: Get the CIM sessions to a specific computer + +This example gets the CIM sessions that are connected to the computer named **Server02**. + +```powershell +Get-CimSession -ComputerName Server02 +``` + +```Output +Id : 2 +Name : CimSession2 +InstanceId : c0095981-52c5-4e7f-a5bb-c4c680541710 +ComputerName : Server02 +Protocol : WSMAN +``` + +### Example 3: Get a list of CIM sessions and then format the list + +This example gets all CIM sessions in the current PowerShell session and displays a table containing +only the **ComputerName** and **InstanceID** properties. + +```powershell +Get-CimSession | Format-Table -Property ComputerName,InstanceId +``` + +```Output +ComputerName InstanceId +------------ ---------- +Server01 d1413bc3-162a-4cb8-9aec-4d2c61253d59 +Server02 c0095981-52c5-4e7f-a5bb-c4c680541710 +``` + +### Example 4: Get all the CIM sessions that have specific names + +This example gets all CIM sessions that have names that begin with **serv**. + +```powershell +Get-CimSession -ComputerName Serv* +``` + +```Output +Id : 1 +Name : CimSession1 +InstanceId : d1413bc-162a-4cb8-9aec-4d2c61253d59 +ComputerName : Server01 +Protocol : WSMAN + +Id : 2 +Name : CimSession2 +InstanceId : c0095981-52c5-4e7f-a5bb-c4c680541710 +ComputerName : Server02 +Protocol : WSMAN +``` + +### Example 5: Get a specific CIM session + +This example gets the CIM session that has an **Id** of 2. + +```powershell +Get-CimSession -ID 2 +``` + +```Output +Id : 2 +Name : CimSession2 +InstanceId : c0095981-52c5-4e7f-a5bb-c4c680541710 +ComputerName : Server02 +Protocol : WSMAN +``` + +## PARAMETERS + +### -ComputerName + +Specifies the name of the computer to get CIM sessions connected to. Wildcard characters are +permitted. + +```yaml +Type: System.String[] +Parameter Sets: ComputerNameSet +Aliases: CN, ServerName + +Required: False +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### -Id + +Specifies the identifier of the CIM session to get. For multiple IDs, use commas to separate the IDs +or use the range operator (`..`) to specify a range of IDs. An **Id** is an integer that uniquely +identifies the CIM session within the current PowerShell session. + +For more information about the range operator, see [about_Operators](../Microsoft.PowerShell.Core/About/about_Operators.md). + +```yaml +Type: System.UInt32[] +Parameter Sets: SessionIdSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -InstanceId + +Specifies the instance IDs of the CIM session to get. + +**InstanceId** is a globally-unique identifier (GUID) that uniquely identifies a CIM session. The +**InstanceId** is unique, even when you have multiple sessions running in PowerShell. + +The **InstanceId** is stored in the **InstanceId** property of the object that represents a CIM +session. + +```yaml +Type: System.Guid[] +Parameter Sets: InstanceIdSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Name + +Gets one or more CIM sessions which contain the specified friendly names. Wildcard characters are +permitted. + +```yaml +Type: System.String[] +Parameter Sets: NameSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.CimSession + +This cmdlet returns a CIM session object. + +## NOTES + +PowerShell includes the following aliases for `Get-CimSession`: + +- Windows: + - `gcms` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Format-Table](../microsoft.powershell.utility/format-table.md) + +[New-CimSession](New-CimSession.md) + +[Remove-CimSession](remove-cimsession.md) + +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md) diff --git a/reference/7.6/CimCmdlets/Invoke-CimMethod.md b/reference/7.6/CimCmdlets/Invoke-CimMethod.md new file mode 100644 index 000000000000..31c9178dd75a --- /dev/null +++ b/reference/7.6/CimCmdlets/Invoke-CimMethod.md @@ -0,0 +1,485 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/invoke-cimmethod?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Invoke-CimMethod +--- + +# Invoke-CimMethod + +## SYNOPSIS +Invokes a method of a CIM class. + +## SYNTAX + +### ClassNameComputerSet (Default) + +``` +Invoke-CimMethod [-ClassName] [-ComputerName ] [[-Arguments] ] + [-MethodName] [-Namespace ] [-OperationTimeoutSec ] [-WhatIf] [-Confirm] + [] +``` + +### ClassNameSessionSet + +``` +Invoke-CimMethod [-ClassName] -CimSession [[-Arguments] ] + [-MethodName] [-Namespace ] [-OperationTimeoutSec ] [-WhatIf] [-Confirm] + [] +``` + +### ResourceUriComputerSet + +``` +Invoke-CimMethod -ResourceUri [-ComputerName ] [[-Arguments] ] + [-MethodName] [-Namespace ] [-OperationTimeoutSec ] [-WhatIf] [-Confirm] + [] +``` + +### CimInstanceSessionSet + +``` +Invoke-CimMethod [-ResourceUri ] [-InputObject] -CimSession + [[-Arguments] ] [-MethodName] [-OperationTimeoutSec ] [-WhatIf] + [-Confirm] [] +``` + +### CimInstanceComputerSet + +``` +Invoke-CimMethod [-ResourceUri ] [-InputObject] [-ComputerName ] + [[-Arguments] ] [-MethodName] [-OperationTimeoutSec ] [-WhatIf] + [-Confirm] [] +``` + +### ResourceUriSessionSet + +``` +Invoke-CimMethod -ResourceUri -CimSession [[-Arguments] ] + [-MethodName] [-Namespace ] [-OperationTimeoutSec ] [-WhatIf] [-Confirm] + [] +``` + +### CimClassComputerSet + +``` +Invoke-CimMethod [-CimClass] [-ComputerName ] [[-Arguments] ] + [-MethodName] [-OperationTimeoutSec ] [-WhatIf] [-Confirm] [] +``` + +### CimClassSessionSet + +``` +Invoke-CimMethod [-CimClass] -CimSession [[-Arguments] ] + [-MethodName] [-OperationTimeoutSec ] [-WhatIf] [-Confirm] [] +``` + +### QueryComputerSet + +``` +Invoke-CimMethod -Query [-QueryDialect ] [-ComputerName ] + [[-Arguments] ] [-MethodName] [-Namespace ] + [-OperationTimeoutSec ] [-WhatIf] [-Confirm] [] +``` + +### QuerySessionSet + +``` +Invoke-CimMethod -Query [-QueryDialect ] -CimSession + [[-Arguments] ] [-MethodName] [-Namespace ] + [-OperationTimeoutSec ] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `Invoke-CimMethod` cmdlet invokes a method of a CIM class or CIM instance using the name-value +pairs specified by the **Arguments** parameter. + +If the **InputObject** parameter is not specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet works on local Windows Management Instrumentation (WMI) using a Component Object Model + (COM) session. +- If either the **ComputerName** parameter or the **CimSession** parameter is specified, then this + cmdlet works against the CIM server specified by either the **ComputerName** parameter or the + **CimSession** parameter. + +If the **InputObject** parameter is specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet uses the CIM session or computer name from the input object. +- If the either the **ComputerName** parameter or the **CimSession** parameter is specified, then + this cmdlet uses the either the **CimSession** parameter value or **ComputerName** parameter + value. This is not a common scenario. + +## EXAMPLES + +### Example 1: Invoke a method + +This example invokes the **Terminate** method of the **Win32_Process** class. + +```powershell +Invoke-CimMethod -Query 'select * from Win32_Process where name like "notepad%"' -MethodName "Terminate" +``` + +### Example 2: Invoke a method using CIM instance object + +This example retrieves the CIM instance object and stores it in a variable named `$x` using the +`Get-CimInstance` cmdlet. The contents of the variable are then used as the **InputObject** for the +`Invoke-CimMethod` cmdlet. The **GetOwner** method is invoked for the **CimInstance**. + +```powershell +$x = Get-CimInstance -Query 'Select * from Win32_Process where name like "notepad%"' +Invoke-CimMethod -InputObject $x -MethodName GetOwner +``` + +### Example 3: Invoke a static method using arguments + +This example invokes the **Create** method named using the **Arguments** parameter. + +```powershell +Invoke-CimMethod -ClassName Win32_Process -MethodName "Create" -Arguments @{ + CommandLine = 'notepad.exe'; CurrentDirectory = "C:\windows\system32" +} +``` + +### Example 4: Client-side validation + +This example performs client-side validation for the **xyz** method by passing a **CimClass** object +to `Invoke-CimMethod`. + +```powershell +$c = Get-CimClass -ClassName Win32_Process +Invoke-CimMethod -CimClass $c -MethodName "xyz" -Arguments @{ CommandLine = 'notepad.exe' } +``` + +## PARAMETERS + +### -Arguments + +Specifies the parameters to pass to the called method. Specify the values for this parameter as +name-value pairs, stored in a hash table. The order of the values entered isn't important. + +```yaml +Type: System.Collections.IDictionary +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -CimClass + +Specifies a CIM class object that represents a CIM class definition on the server. Use this +parameter when invoking a static method of a class. + +You can use the `Get-CimClass` cmdlet to retrieve a class definition from the server. + +Using this parameter results in better client side schema validations. + +```yaml +Type: Microsoft.Management.Infrastructure.CimClass +Parameter Sets: CimClassComputerSet, CimClassSessionSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -CimSession + +Runs the command using the specified CIM session. Enter a variable that contains the CIM session, or +a command that creates or gets the CIM session, such as the `New-CimSession` or `Get-CimSession` +cmdlets. For more information, see +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: ClassNameSessionSet, CimInstanceSessionSet, CimClassSessionSet, QuerySessionSet, ResourceUriSessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ClassName + +Specifies the name of the CIM class for which to perform the operation. This parameter is only used +for static methods. You can use tab completion to browse the list of classes, because PowerShell +gets a list of classes from the local WMI server to provide a list of class names. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet +Aliases: Class + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer on which you want to run the CIM operation. You can specify a +fully qualified domain name (FQDN), a NetBIOS name, or an IP address. + +When using this parameter, the cmdlet creates a temporary session to the specified computer using +the WsMan protocol. Otherwise, the cmdlet performs the operation on the local computer using +Component Object Model (COM). + +Connect using a CIM session for better performance when multiple operations are being performed on +the same computer. + +```yaml +Type: System.String[] +Parameter Sets: ClassNameComputerSet, ResourceUriComputerSet, CimClassComputerSet, CimInstanceComputerSet, QueryComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -InputObject + +Specifies a CIM instance object to use as input to invoke a method. This parameter can only be used +to invoke instance methods. To invoke class static methods, use the **Class** parameter or the +**CimClass** parameter. + +```yaml +Type: Microsoft.Management.Infrastructure.CimInstance +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet +Aliases: CimInstance + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -MethodName + +Specifies the name of the CIM method to invoke. This parameter is mandatory and cannot be null or +empty. To invoke static method of a CIM class use the **ClassName** or the **CimClass** parameter. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: Name + +Required: True +Position: 2 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace for the CIM operation. The default namespace is **root/cimv2**. You can use +tab completion to browse the list of namespaces, because PowerShell gets a list of namespaces from +the local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet, ResourceUriComputerSet, ResourceUriSessionSet, QuerySessionSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value is 0, which means that the cmdlet uses the default timeout value for the server. + +If the **OperationTimeoutSec** parameter is set to a value less than the default connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Query + +Specifies a query to run on the CIM server. A method is invoked on the instances received as a +result of the query. You can specify the query dialect using the **QueryDialect** parameter. + +If the value specified contains double quotes (`"`), single quotes (`'`), or a backslash (`\`), you +must escape those characters by prefixing them with the backslash (`\`) character. If the value +specified uses the WQL LIKE operator, then you must escape the following characters by enclosing +them in square brackets (`[]`): percent (`%`), underscore (`_`), or opening square bracket (`[`). + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -QueryDialect + +Specifies the query language used for the Query parameter. The acceptable values for this parameter +are: **WQL** or **CQL**. + +The default value is **WQL**. + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: WQL +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ResourceUri + +Specifies the resource uniform resource identifier (URI) of the resource class or instance. +The URI is used to identify a specific type of resource, such as disks or processes, on a computer. + +A URI consists of a prefix and a path to a resource. For example: + +`http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk` + +`http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings` + +By default, if you do not specify this parameter, the DMTF standard resource URI +`http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/` is used and the class name is appended to it. + +**ResourceURI** can only be used with CIM sessions created using the WSMan protocol, or when +specifying the **ComputerName** parameter, which creates a CIM session using WSMan. + +When you specify this parameter without specifying the **ComputerName** parameter, or when you +specify a CIM session created using DCOM protocol, you get an error. The DCOM protocol does not +support the **ResourceURI** parameter. + +If both the **ResourceUri** parameter and the **Filter** parameter are specified, the **Filter** +parameter is ignored. + +```yaml +Type: System.Uri +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet +Aliases: + +Required: True (ResourceUriSessionSet, ResourceUriComputerSet), False (CimInstanceSessionSet, CimInstanceComputerSet) +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](../Microsoft.PowerShell.Core/About/about_CommonParameters.md). + +## INPUTS + +### Microsoft.Management.Infrastructure.CimClass + +You can pipe a CIM class to this cmdlet. + +### Microsoft.Management.Infrastructure.CimInstance + +You can pipe a CIM instance to this cmdlet. + +## OUTPUTS + +### System.Management.Automation.PSCustomObject + +This cmdlet returns an object. + +## NOTES + +PowerShell includes the following aliases for `Invoke-CimMethod`: + +- Windows: + - `icim` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-CimClass](get-cimclass.md) + +[Get-CimInstance](get-ciminstance.md) + +[Get-CimSession](Get-CimSession.md) + +[New-CimSession](New-CimSession.md) diff --git a/reference/7.6/CimCmdlets/New-CimInstance.md b/reference/7.6/CimCmdlets/New-CimInstance.md new file mode 100644 index 000000000000..cc03c86ef4a0 --- /dev/null +++ b/reference/7.6/CimCmdlets/New-CimInstance.md @@ -0,0 +1,421 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/new-ciminstance?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: New-CimInstance +--- + +# New-CimInstance + +## SYNOPSIS +Creates a CIM instance. + +## SYNTAX + +### ClassNameComputerSet (Default) + +``` +New-CimInstance [-ClassName] [-Key ] [[-Property] ] + [-Namespace ] [-OperationTimeoutSec ] [-ComputerName ] [-ClientOnly] + [-WhatIf] [-Confirm] [] +``` + +### ClassNameSessionSet + +``` +New-CimInstance [-ClassName] [-Key ] [[-Property] ] + [-Namespace ] [-OperationTimeoutSec ] -CimSession [-ClientOnly] + [-WhatIf] [-Confirm] [] +``` + +### ResourceUriSessionSet + +``` +New-CimInstance -ResourceUri [-Key ] [[-Property] ] + [-Namespace ] [-OperationTimeoutSec ] -CimSession [-WhatIf] + [-Confirm] [] +``` + +### ResourceUriComputerSet + +``` +New-CimInstance -ResourceUri [-Key ] [[-Property] ] + [-Namespace ] [-OperationTimeoutSec ] [-ComputerName ] [-WhatIf] + [-Confirm] [] +``` + +### CimClassSessionSet + +``` +New-CimInstance [-CimClass] [[-Property] ] [-OperationTimeoutSec ] + -CimSession [-ClientOnly] [-WhatIf] [-Confirm] [] +``` + +### CimClassComputerSet + +``` +New-CimInstance [-CimClass] [[-Property] ] [-OperationTimeoutSec ] + [-ComputerName ] [-ClientOnly] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `New-CimInstance` cmdlet creates an instance of a CIM class based on the class definition on +either the local computer or a remote computer. By default, the `New-CimInstance` cmdlet creates an +instance on the local computer. + +## EXAMPLES + +### Example 1: Create an instance of a CIM class + +This example creates an instance of a CIM Class named win32_environment in the root/cimv2 namespace +on the computer. + +```powershell +New-CimInstance -ClassName Win32_Environment -Property @{Name="testvar";VariableValue="testvalue";UserName="domain\user"} +``` + +No client side validation is performed if the class does not exist, the properties are wrong, or if +the server rejects the call. If the instance is created successfully, the cmdlet outputs the newly +created instance. + +### Example 2: Create an instance of a CIM class using a class schema + +This example retrieves a CIM class object and stores it in a variable named `$class`. The contents +of the variable are then passed to the `New-CimInstance` cmdlet. + +```powershell +$class = Get-CimClass -ClassName Win32_Environment +New-CimInstance -CimClass $class -Property @{Name="testvar";VariableValue="testvalue";UserName="Contoso\User1"} +``` + +### Example 3: Create a dynamic instance on the client + +This example creates a dynamic instance of a CIM class named **Win32_Process** on the client +computer without getting the instance from the server. The new instance is stored in the variable +`$a`. This dynamic instance can be used to perform operations if the instance with this key exists +on the server. + +```powershell +$a = New-CimInstance -ClassName Win32_Process -Property @{Handle=0} -Key Handle -ClientOnly +Get-CimInstance -CimInstance $a +Invoke-CimMethod -CimInstance $a -MethodName GetOwner +``` + +```Output +ProcessId Name HandleCount WorkingSetSize VirtualSize +--------- ---- ----------- -------------- ----------- +0 System Idle Process 0 8192 8192 + +Domain : +ReturnValue : 2 +User : +PSComputerName : +``` + +The `Get-CimInstance` cmdlet then retrieves a particular single instance. The `Invoke-CimMethod` +cmdlet calls the **GetOwner** method on the retrieved instance. + +### Example 4: Create an instance for a CIM class of a specific namespace + +This example gets an instance of a CIM class named **MSFT_Something** in the namespace +**root/somewhere** and stores it in a variable named `$class`. The variable is passed to the +`New-CimInstance` cmdlet to create a new CIM instance and perform client side validations on the new +instance. + +```powershell +$class = Get-CimClass -ClassName MSFT_Something -Namespace root/somewhere +New-CimInstance -CimClass $class -Property @{"Prop1"=1;"Prop2"="value"} -ClientOnly +``` + +In this example, using the **CimClass** parameter instead of the **ClassName** parameter validates +that **Prop1** and **Prop2** actually exist and that the keys are marked correctly. + +You cannot use the **ComputerName** or **CimSession** parameter with the **ClientOnly** parameter. + +## PARAMETERS + +### -CimClass + +Specifies a CIM class object that represents the type of the instance. Use the `Get-CimClass` cmdlet +to retrieve the class declaration from a computer. Using this parameter results in better client +side schema validations. + +```yaml +Type: Microsoft.Management.Infrastructure.CimClass +Parameter Sets: CimClassSessionSet, CimClassComputerSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -CimSession + +Runs the command using the specified CIM session. Enter a variable that contains the CIM session, or +a command that creates or gets the CIM session, such as the `New-CimSession` or `Get-CimSession` +cmdlets. For more information, see +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: ClassNameSessionSet, ResourceUriSessionSet, CimClassSessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ClassName + +Specifies the name of the CIM class of which the operation creates an instance. NOTE: You can use +tab completion to browse the list of classes, because PowerShell gets a list of classes from the +local WMI server to provide a list of class names. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ClientOnly + +Indicates that the instance is only created in PowerShell without going to the CIM server. You can +use this parameter to create an in-memory CIM instance for use in subsequent PowerShell operations. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet, CimClassSessionSet, CimClassComputerSet +Aliases: Local + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer on which you want to run the CIM operation. You can specify a +fully qualified domain name (FQDN), a NetBIOS name, or an IP address. + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WSMan protocol. + +If you do not specify this parameter, the cmdlet performs the operation on the local computer using +Component Object Model (COM). + +If multiple operations are being performed on the same computer, connecting using a CIM session +gives better performance. + +```yaml +Type: System.String[] +Parameter Sets: ClassNameComputerSet, ResourceUriComputerSet, CimClassComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Key + +Specifies the properties that are used as keys. **CimSession** and **ComputerName** cannot be used +when **Key** is specified. + +```yaml +Type: System.String[] +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet, ResourceUriSessionSet, ResourceUriComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace of the class for the new instance. The default namespace is **root/cimv2**. +You can use tab completion to browse the list of namespaces, because PowerShell gets a list of +namespaces from the local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet, ResourceUriSessionSet, ResourceUriComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the CIM server. By default, +the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the +server. If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Property + +Specifies the properties of the CIM instance using a hash table (name-value pairs). + +If you specify the **CimClass** parameter, then the `New-CimInstance` cmdlet performs a property +validation on the client to make sure that the properties specified are consistent with the class +declaration on the server. If the **CimClass** parameter is not specified, then the property +validation is done on the server. + +```yaml +Type: System.Collections.IDictionary +Parameter Sets: (All) +Aliases: Arguments + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ResourceUri + +Specifies the resource uniform resource identifier (URI) of the resource class or instance. The URI +is used to identify a specific type of resource, such as disks or processes, on a computer. + +A URI consists of a prefix and a path to a resource. For example: + +`http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk` + +`http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings` + +By default, if you do not specify this parameter, the DMTF standard resource URI +`http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/` is used and the class name is appended to it. + +**ResourceURI** can only be used with CIM sessions created using the WSMan protocol, or when +specifying the **ComputerName** parameter, which creates a CIM session using WSMan. If you specify +this parameter without specifying the **ComputerName** parameter, or if you specify a CIM session +created using DCOM protocol, you will get an error, because the DCOM protocol does not support the +**ResourceURI** parameter. + +If both the **ResourceUri** parameter and the **Filter** parameter are specified, the **Filter** +parameter is ignored. + +```yaml +Type: System.Uri +Parameter Sets: ResourceUriSessionSet, ResourceUriComputerSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](../Microsoft.PowerShell.Core/About/about_CommonParameters.md). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.CimInstance + +This cmdlet returns an object that contains the CIM instance information. + +## NOTES + +PowerShell includes the following aliases for `New-CimInstance`: + +- Windows: + - `ncim` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-CimClass](get-cimclass.md) + +[Get-CimInstance](get-ciminstance.md) + +[Remove-CimInstance](remove-ciminstance.md) + +[Set-CimInstance](Set-CimInstance.md) diff --git a/reference/7.6/CimCmdlets/New-CimSession.md b/reference/7.6/CimCmdlets/New-CimSession.md new file mode 100644 index 000000000000..f28d94f87161 --- /dev/null +++ b/reference/7.6/CimCmdlets/New-CimSession.md @@ -0,0 +1,388 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/new-cimsession?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: New-CimSession +--- +# New-CimSession + +## SYNOPSIS + +Creates a CIM session. + +## SYNTAX + +### CredentialParameterSet (Default) + +``` +New-CimSession [-Authentication ] [[-Credential] ] + [[-ComputerName] ] [-Name ] [-OperationTimeoutSec ] [-SkipTestConnection] + [-Port ] [-SessionOption ] [] +``` + +### CertificateParameterSet + +``` +New-CimSession [-CertificateThumbprint ] [[-ComputerName] ] [-Name ] + [-OperationTimeoutSec ] [-SkipTestConnection] [-Port ] + [-SessionOption ] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `New-CimSession` cmdlet creates a CIM session. A CIM session is a client-side object +representing a connection to a local computer or a remote computer. The CIM session contains +information about the connection, such as **ComputerName**, the protocol used, or various +identifiers. + +This cmdlet returns a CIM session object that can be used by all other CIM cmdlets. + +## EXAMPLES + +### Example 1: Create a CIM session with default options + +This example creates a local CIM session with default options. If **ComputerName** is not specified, +`New-CimSession` creates a DCOM session to the local computer. + +```powershell +New-CimSession +``` + +### Example 2: Create a CIM session to a specific computer + +This example creates a CIM session to the computer specified by **ComputerName**. +By default, `New-CimSession` creates a WSMan session when **ComputerName** is specified. + +```powershell +New-CimSession -ComputerName Server01 +``` + +### Example 3: Create a CIM session to multiple computers + +This example creates a CIM session to each of the computers specified by **ComputerName**, in the +comma separated list. + +```powershell +New-CimSession -ComputerName Server01,Server02,Server03 +``` + +### Example 4: Create a CIM session with a friendly name + +This example creates a remote CIM session to each of the computers specified by **ComputerName**, in +the comma separated list, and assigns a friendly name to the new sessions, by specifying **Name**. + +```powershell +New-CimSession -ComputerName Server01,Server02 -Name FileServers +Get-CimSession -Name File* +``` + +You can use the friendly name of a CIM session to refer to the session in other CIM cmdlets, for +example, [Get-CimSession](Get-CimSession.md). + +### Example 5: Create a CIM session to a computer using a PSCredential object + +This example creates a CIM session to the computer specified by **ComputerName**, using the +**PSCredential** object specified by **Credential**, and the authentication type specified by +**Authentication**. + +```powershell +New-CimSession -ComputerName Server01 -Credential $cred -Authentication Negotiate +``` + +You can create a **PSCredential** object using the +[`Get-Credential`](../Microsoft.PowerShell.Security/Get-Credential.md) cmdlet. + +### Example 6: Create a CIM session to a computer using a specific port + +This example creates a CIM session to the computer specified by **ComputerName** using the TCP port +specified by **Port**. + +```powershell +New-CimSession -ComputerName Server01 -Port 1234 +``` + +### Example 7: Create a CIM session using DCOM + +This example creates a CIM session using the Distributed COM (DCOM) protocol instead of WSMan. + +```powershell +$SessionOption = New-CimSessionOption -Protocol DCOM +New-CimSession -ComputerName Server1 -SessionOption $SessionOption +``` + +## PARAMETERS + +### -Authentication + +Specifies the authentication type used for the user's credentials. The acceptable values for this +parameter are: + +- Default +- Digest +- Negotiate +- Basic +- Kerberos +- NtlmDomain +- CredSsp + +You cannot use the **NtlmDomain** authentication type for connection to the local computer. **CredSSP** +authentication is available only in Windows Vista, Windows Server 2008, and later versions of +Windows. + +> [!CAUTION] +> Credential Security Service Provider (CredSSP) authentication is designed for commands that +> require authentication on more than one resource, such as accessing a remote network share. This +> mechanism increases the security risk of the remote operation. If the remote computer is +> compromised, the credentials that are passed to it can be used to control the network session. + +```yaml +Type: Microsoft.Management.Infrastructure.Options.PasswordAuthenticationMechanism +Parameter Sets: CredentialParameterSet +Aliases: +Accepted values: Default, Digest, Negotiate, Basic, Kerberos, NtlmDomain, CredSsp + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -CertificateThumbprint + +Specifies the digital public key certificate (X.509) of a user account that has permission to +perform this action. Enter the certificate thumbprint of the certificate. + +Certificates are used in client certificate-based authentication. They can be mapped only to local +user accounts; they do not work with domain accounts. + +To get a certificate thumbprint, use the +[`Get-Item`](../Microsoft.Powershell.Management/Get-Item.md) or +[`Get-ChildItem`](../Microsoft.Powershell.Management/Get-ChildItem.md) cmdlets in the PowerShell +Certificate Provider. + +For more information, see [about_Certificate_Provider](../Microsoft.PowerShell.Security/About/about_Certificate_Provider.md). + +```yaml +Type: System.String +Parameter Sets: CertificateParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer to which to create the CIM session. Specify either a single +computer name, or multiple computer names separated by a comma. + +If **ComputerName** is not specified, a CIM session to the local computer is created. You can +specify the value for computer name in one of the following formats: + +- One or more NetBIOS names +- One or more IP addresses +- One or more fully qualified domain names. + +If the computer is in a different domain than the user, you must specify the fully qualified domain +name. + +```yaml +Type: System.String[] +Parameter Sets: (All) +Aliases: CN, ServerName + +Required: False +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Credential + +Specifies a user account that has permission to perform this action. If **Credential** is not +specified, the current user account is used. + +Specify the value for **Credential** using one of the following formats: + +- A user name: "User01" +- A domain name and a user name: "Domain01\User01" +- A user principal name: "User@Domain.com" +- A PSCredential object, such as one returned by the [`Get-Credential`](../Microsoft.PowerShell.Security/Get-Credential.md) cmdlet. + +When you type a user name, you are prompted for a password. + +```yaml +Type: System.Management.Automation.PSCredential +Parameter Sets: CredentialParameterSet +Aliases: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Name + +Specifies a friendly name for the CIM session. + +You can use the name to refer to the CIM session when using other cmdlets, such as the [Get-CimSession](Get-CimSession.md) cmdlet. +The name is not required to be unique to the computer or the current session. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Duration for which the cmdlet waits for a response from the server. + +By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout +value for the server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Port + +Specifies the network port on the remote computer that is used for this connection. To connect to a +remote computer, the remote computer must be listening on the port that the connection uses. The +default ports are 5985 (the WinRM port for HTTP) and 5986 (the WinRM port for HTTPS). + +Before using an alternate port, you must configure the WinRM listener on the remote computer to +listen at that port. Use the following commands to configure the listener: + +`winrm delete winrm/config/listener?Address=*+Transport=HTTP` + +`winrm create winrm/config/listener?Address=*+Transport=HTTP @{Port="\"}` + +Do not use the **Port** parameter unless you must. The port setting in the command applies to all +computers or sessions on which the command runs. An alternate port setting might prevent the command +from running on all computers. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -SessionOption + +Sets advanced options for the new CIM session. Enter the name of a **CimSessionOption** object +created using the [`New-CimSessionOption`](New-CimSessionOption.md) cmdlet. + +```yaml +Type: Microsoft.Management.Infrastructure.Options.CimSessionOptions +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -SkipTestConnection + +By default, the `New-CimSession` cmdlet establishes a connection with a remote WS-Management +endpoint for two reasons: to verify that the remote server is listening on the port number that is +specified using the **Port** parameter, and to verify the specified account credentials. The +verification is accomplished using a standard WS-Identity operation. You can add the +**SkipTestConnection** switch parameter if the remote WS-Management endpoint cannot use WS-Identify, +or to reduce some data transmission time. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](../Microsoft.PowerShell.Core/About/about_CommonParameters.md). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.CimSession + +This cmdlet returns a CIM session object. + +## NOTES + +PowerShell includes the following aliases for `New-CimSession`: + +- Windows: + - `ncms` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-ChildItem](../Microsoft.Powershell.Management/Get-ChildItem.md) + +[Get-Credential](../Microsoft.PowerShell.Security/Get-Credential.md) + +[Get-Item](../Microsoft.Powershell.Management/Get-Item.md) + +[Get-CimSession](Get-CimSession.md) + +[Remove-CimSession](Remove-CimSession.md) + +[New-CimSessionOption](New-CimSessionOption.md) + +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md) diff --git a/reference/7.6/CimCmdlets/New-CimSessionOption.md b/reference/7.6/CimCmdlets/New-CimSessionOption.md new file mode 100644 index 000000000000..d22cecd91baf --- /dev/null +++ b/reference/7.6/CimCmdlets/New-CimSessionOption.md @@ -0,0 +1,499 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/new-cimsessionoption?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: New-CimSessionOption +--- + +# New-CimSessionOption + +## SYNOPSIS +Specifies advanced options for the New-CimSession cmdlet. + +## SYNTAX + +### ProtocolTypeSet (Default) + +``` +New-CimSessionOption [-Protocol] [-UICulture ] [-Culture ] + [] +``` + +### WSManParameterSet + +``` +New-CimSessionOption [-NoEncryption] [-SkipCACheck] [-SkipCNCheck] [-SkipRevocationCheck] + [-EncodePortInServicePrincipalName] [-Encoding ] [-HttpPrefix ] + [-MaxEnvelopeSizeKB ] [-ProxyAuthentication ] + [-ProxyCertificateThumbprint ] [-ProxyCredential ] [-ProxyType ] + [-UseSsl] [-UICulture ] [-Culture ] [] +``` + +### DcomParameterSet + +``` +New-CimSessionOption [-Impersonation ] [-PacketIntegrity] [-PacketPrivacy] + [-UICulture ] [-Culture ] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `New-CimSessionOption` cmdlet creates an instance of a CIM session options object. You use a CIM +session options object as input to the `New-CimSession` cmdlet to specify the options for a CIM +session. + +This cmdlet has two parameter sets, one for WsMan options and one for Distributed Component Object +Model (DCOM) options. Depending on which parameters you use, the cmdlet returns either an instance +of DCOM session options or returns WsMan session options. + +## EXAMPLES + +### Example 1: Create a CIM session options object for DCOM + +This example creates a CIM session options object for the DCOM protocol and stores it in a variable +named `$so`. The contents of the variable are then passed to the `New-CimSession` cmdlet. +`New-CimSession` then creates a new CIM session with the remote server named Server01, using the +options defined in the variable. + +```powershell +$so = New-CimSessionOption -Protocol DCOM +New-CimSession -ComputerName Server01 -SessionOption $so +``` + +### Example 2: Create a CIM session options object for WsMan + +This example creates a CIM session options object for the WsMan protocol. The object contains +configuration for the authentication mode of **Kerberos** specified by the **ProxyAuthentication** +parameter, the credentials specified by the **ProxyCredential** parameter, and specifies that the +command is to skip the CA check, skip the CN check, and use SSL. + +```powershell +New-CimSessionOption -ProxyAuthentication Kerberos -ProxyCredential $cred -SkipCACheck -SkipCNCheck -UseSsl +``` + +### Example 3: Create a CIM session options object with the culture specified + +```powershell +New-CimSessionOption -Culture Fr-Fr -Protocol Wsman +``` + +This example specifies the culture that is used for the CIM session. By default, the culture of the +client is used when performing operations. However, the default culture can be overridden using the +**Culture** parameter. + +## PARAMETERS + +### -Culture + +Specifies the user interface culture to use for the CIM session. Specify the value for this +parameter using one of the following formats: + +- A culture name in `-` format such as "EN-US". +- A variable that contains a **CultureInfo** object. +- A command that gets a **CultureInfo** object, such as [Get-Culture](../Microsoft.PowerShell.Utility/Get-Culture.md) + +```yaml +Type: System.Globalization.CultureInfo +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -EncodePortInServicePrincipalName + +Indicates that the Kerberos connection is connecting to a service whose service principal name (SPN) +includes the service port number. This type of connection is not common. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Encoding + +Specifies the encoding used for the WsMan protocol. The acceptable values for this parameter are: +**Default**, **Utf8**, or **Utf16**. + +```yaml +Type: Microsoft.Management.Infrastructure.Options.PacketEncoding +Parameter Sets: WSManParameterSet +Aliases: +Accepted values: Default, Utf8, Utf16 + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -HttpPrefix + +Specifies the part of the HTTP URL after the computer name and port number. Changing this is not +common. By default, the value of this parameter is **/wsman**. + +```yaml +Type: System.Uri +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Impersonation + +Creates a DCOM session to Windows Management Instrumentation (WMI) using impersonation. + +Valid values for this parameter are: + +- Default: DCOM can choose the impersonation level using its normal security negotiation algorithm. +- None: The client is anonymous to the server. The server process can impersonate the client, but + the impersonation token does not contain any information and cannot be used. +- Identify: Allows objects to query the credentials of the caller. +- Impersonate: Allows objects to use the credentials of the caller. +- Delegate: Allows objects to permit other objects to use the credentials of the caller. + +If **Impersonation** is not specified, the `New-CimSession` cmdlet uses the value of +**Impersonate**. + +```yaml +Type: Microsoft.Management.Infrastructure.Options.ImpersonationType +Parameter Sets: DcomParameterSet +Aliases: +Accepted values: Default, None, Identify, Impersonate, Delegate + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -MaxEnvelopeSizeKB + +Specifies the size limit of WsMan XML messages for either direction. + +```yaml +Type: System.UInt32 +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -NoEncryption + +Specifies that data encryption is turned off. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -PacketIntegrity + +Specifies that the DCOM session created to WMI uses the Component Object Model (COM) +_PacketIntegrity_ functionality. By default, all CIM sessions created using DCOM have the +**PacketIntegrity** parameter set to **True**. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: DcomParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -PacketPrivacy + +Creates a DCOM session to WMI using the COM _PacketPrivacy_. By default, all CIM sessions created +using DCOM have the **PacketPrivacy** parameter set to **true**. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: DcomParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Protocol + +Specifies the protocol to use. The acceptable values for this parameter are: **DCOM**, **Default**, +or **Wsman**. + +```yaml +Type: Microsoft.Management.Infrastructure.CimCmdlets.ProtocolType +Parameter Sets: ProtocolTypeSet +Aliases: +Accepted values: Dcom, Default, Wsman + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ProxyAuthentication + +Specifies the authentication method to use for proxy resolution. The acceptable values for this +parameter are: **Default**, **Digest**, **Negotiate**, **Basic**, **Kerberos**, **NtlmDomain**, or +**CredSsp**. + +```yaml +Type: Microsoft.Management.Infrastructure.Options.PasswordAuthenticationMechanism +Parameter Sets: WSManParameterSet +Aliases: +Accepted values: Default, Digest, Negotiate, Basic, Kerberos, NtlmDomain, CredSsp + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ProxyCertificateThumbprint + +Specifies the (x.509) digital public key certificate of a user account for proxy authentication. +Enter the certificate thumbprint of the certificate. Certificates are used in client +certificate-based authentication. They can only be mapped to local user accounts and they do not +work with domain accounts. + +To get a certificate thumbprint, use the `Get-Item` or `Get-ChildItem` cmdlets in the PowerShell +Cert: drive. + +```yaml +Type: System.String +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ProxyCredential + +Specifies the credentials to use for proxy authentication. Enter one of the following: + +- A variable that contains a PSCredential object. +- A command that gets a PSCredential object, such as `Get-Credential` + +If this option is not set, then you cannot specify any credentials. + +```yaml +Type: System.Management.Automation.PSCredential +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProxyType + +Specifies the host name resolution mechanism to use. The acceptable values for this parameter are: +**None**, **WinHttp**, **Auto**, or **InternetExplorer**. + +The default value of this parameter is **InternetExplorer**. + +```yaml +Type: Microsoft.Management.Infrastructure.Options.ProxyType +Parameter Sets: WSManParameterSet +Aliases: +Accepted values: None, WinHttp, Auto, InternetExplorer + +Required: False +Position: Named +Default value: InternetExplorer +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -SkipCACheck + +Indicates that when connecting over HTTPS, the client does not validate that the server certificate +is signed by a trusted certification authority (CA). + +Use this parameter only when the remote computer is trusted using another mechanism, such as when +the remote computer is part of a network that is physically secure and isolated, or when the remote +computer is listed as a trusted host in a WinRM configuration. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -SkipCNCheck + +Indicates that the certificate common name (CN) of the server does not need to match the hostname of +the server. Use this parameter for remote operations only with trusted computers that use the HTTPS +protocol. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -SkipRevocationCheck + +Indicates that the revocation check for server certificates is skipped. Use this parameter only for +trusted computers. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -UICulture + +Specifies the user interface culture to use for the CIM session. Specify the value for this +parameter using one of the following formats: + +- A culture name in `-` format such as "EN-US". +- A variable that contains a CultureInfo object. +- A command that gets a CultureInfo object, such as `Get-Culture`. + +```yaml +Type: System.Globalization.CultureInfo +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -UseSsl + +Indicates that SSL should be used to establish a connection to the remote computer. By default, SSL +is not used. WsMan encrypts all content that is transmitted over the network, even when using HTTP. + +This parameter lets you specify the additional protection of HTTPS instead of HTTP. If SSL is not +available on the port used for the connection and you specify this parameter, then the command +fails. + +It is recommended that you use this parameter only when the **PacketPrivacy** parameter is not +specified. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: WSManParameterSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### Microsoft.Management.Infrastructure.Options.CimSessionOptions + +This cmdlet returns an object that contains CIM session options information. + +## NOTES + +PowerShell includes the following aliases for `New-CimSessionOption`: + +- Windows: + - `ncso` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-ChildItem](../microsoft.powershell.management/get-childitem.md) + +[Get-Credential](../microsoft.powershell.security/get-credential.md) + +[Get-Culture](../microsoft.powershell.utility/get-culture.md) + +[Get-Item](../microsoft.powershell.management/get-item.md) + +[New-CimSession](New-CimSession.md) diff --git a/reference/7.6/CimCmdlets/Register-CimIndicationEvent.md b/reference/7.6/CimCmdlets/Register-CimIndicationEvent.md new file mode 100644 index 000000000000..d9f5c673860e --- /dev/null +++ b/reference/7.6/CimCmdlets/Register-CimIndicationEvent.md @@ -0,0 +1,412 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +no-loc: [-Forward] +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/register-cimindicationevent?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Register-CimIndicationEvent +--- +# Register-CimIndicationEvent + +## SYNOPSIS +Subscribes to indications using a filter expression or a query expression. + +## SYNTAX + +### ClassNameComputerSet (Default) + +``` +Register-CimIndicationEvent [-Namespace ] [-ClassName] + [-OperationTimeoutSec ] [-ComputerName ] [[-SourceIdentifier] ] + [[-Action] ] [-MessageData ] [-SupportEvent] [-Forward] + [-MaxTriggerCount ] [] +``` + +### ClassNameSessionSet + +``` +Register-CimIndicationEvent [-Namespace ] [-ClassName] + [-OperationTimeoutSec ] -CimSession [[-SourceIdentifier] ] + [[-Action] ] [-MessageData ] [-SupportEvent] [-Forward] + [-MaxTriggerCount ] [] +``` + +### QueryExpressionSessionSet + +``` +Register-CimIndicationEvent [-Namespace ] [-Query] [-QueryDialect ] + [-OperationTimeoutSec ] -CimSession [[-SourceIdentifier] ] + [[-Action] ] [-MessageData ] [-SupportEvent] [-Forward] + [-MaxTriggerCount ] [] +``` + +### QueryExpressionComputerSet + +``` +Register-CimIndicationEvent [-Namespace ] [-Query] [-QueryDialect ] + [-OperationTimeoutSec ] [-ComputerName ] [[-SourceIdentifier] ] + [[-Action] ] [-MessageData ] [-SupportEvent] [-Forward] + [-MaxTriggerCount ] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `Register-CimIndicationEvent` cmdlet subscribes to indications using an indication class name or +a query expression. Use the **SourceIdentifier** parameter give a name to the subscription. + +This cmdlet returns an **EventSubscription** object. You can use this object to cancel the +subscription. + +## EXAMPLES + +### Example 1: Register the events generated by a class + +This example subscribes to the events generated by the class named **Win32_ProcessStartTrace**. This +class raises an event whenever a process starts. + +```powershell +Register-CimIndicationEvent -ClassName 'Win32_ProcessStartTrace' -SourceIdentifier "ProcessStarted" +Get-Event -SourceIdentifier "ProcessStarted" +``` + +The `Get-Event` cmdlet gets the events with **ProcessStarted** subscription. For more information, +see [Get-Event](../Microsoft.PowerShell.Utility/Get-Event.md). + +> [!NOTE] +> For this example, you must run PowerShell as an Administrator. + +### Example 2: Register the events using a query + +This example uses a query to subscribe to an event generated whenever there is a change in +the instance of a class named **Win32_LocalTime**. + +```powershell +$query = "SELECT * FROM CIM_InstModification WHERE TargetInstance ISA 'Win32_LocalTime'" +Register-CimIndicationEvent -Query $query -SourceIdentifier "Timer" +``` + +### Example 3: Run a script when the event arrives + +This example shows how to use an action in response to an event. The variable `$action` holds the +script block for **Action**, which uses the `$event` variable to access the event received from CIM. + +```powershell +$action = { + $name = $event.SourceEventArgs.NewEvent.ProcessName + $id = $event.SourceEventArgs.NewEvent.ProcessId + Write-Host -Object "New Process Started : Name = $name + ID = $id" +} +Register-CimIndicationEvent -ClassName 'Win32_ProcessStartTrace' -SourceIdentifier "ProcessStarted" -Action $action +``` + +For more information, see [Win32_ProcessStartTrace](/previous-versions/windows/desktop/krnlprov/win32-processstarttrace). + +### Example 4: Register the events on a remote computer + +This example subscribes to events on a remote computer named **Server01**. Events received from the +CIM server are stored in the event queue in the current PowerShell session and then runs a local +`Get-Event` to retrieve the events. + +```powershell +Register-CimIndicationEvent -ClassName 'Win32_ProcessStartTrace' -SourceIdentifier "ProcessStarted" -ComputerName Server01 +Get-Event -SourceIdentifier "ProcessStarted" +``` + +## PARAMETERS + +### -Action + +Specifies the commands that handle the events. The commands specified by this parameter run when an +event is raised, instead of sending the event to the event queue. Enclose the commands in braces +(`{}`) to create a script block. + +The script block specified with **Action** can include the `$Event`, `$EventSubscriber`, `$Sender`, +`$SourceEventArgs`, and `$SourceArgs` automatic variables, which provide information about the event +to the **Action** script block. For more information, see +[About Automatic Variables](../microsoft.powershell.core/about/about_automatic_variables.md). + +```yaml +Type: System.Management.Automation.ScriptBlock +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -CimSession + +Runs the command using the specified CIM session. Enter a variable that contains the CIM session, or +a command that creates or gets the CIM session, such as the `New-CimSession` or `Get-CimSession` +cmdlets. For more information, see +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession +Parameter Sets: ClassNameSessionSet, QueryExpressionSessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ClassName + +Specifies the indication class to which you are subscribing. You can use tab completion to browse +the list of classes, because PowerShell gets a list of classes from the local WMI server to provide +a list of class names. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, ClassNameSessionSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer on which you want to run the CIM operation. You can specify a +fully qualified domain name (FQDN), a NetBIOS name, or an IP address. + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WsMan protocol. If you do not specify this parameter, the cmdlet performs operation on the +local system using Component Object Model (COM). + +If multiple operations are being performed on the same computer, connect using a CIM session for +better performance. + +```yaml +Type: System.String +Parameter Sets: ClassNameComputerSet, QueryExpressionComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Forward + +Indicates that events for the subscription are forwarded to the session on the local computer. Use +this parameter when you are registering for events on a remote computer or in a remote session. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -MaxTriggerCount + +Parameter to indicate that the subscriber should be auto-unregistered after being triggered for +specified times. If the value is equal or less than zero, there is no limit on the number of times +the event can be triggered without being unregistered. + +```yaml +Type: System.Int32 +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -MessageData + +Specifies any additional data to associate with this event subscription. The value of this parameter +appears in the **MessageData** property of all the events associated with this subscription. + +```yaml +Type: System.Management.Automation.PSObject +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace for the CIM operation. The default namespace is **root/cimv2**. You can use +tab completion to browse the list of namespaces, because PowerShell gets a list of namespaces from +the local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value of this parameter is 0, which means that the cmdlet uses the default timeout value for the +server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Query + +Specifies a query to run on the CIM server. If the value specified contains double quotes `"`, +single quotes `'`, or a backslash `\`, you must escape those characters by prefixing them with the +backslash character. If the value specified uses the WQL LIKE operator, then you must escape the +following characters by enclosing them in square brackets `[]`: percent `%`, underscore `_`, or +opening square bracket `[`. + +```yaml +Type: System.String +Parameter Sets: QueryExpressionSessionSet, QueryExpressionComputerSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -QueryDialect + +Specifies the query language used for the **Query** parameter. The acceptable values for this +parameter are: **WQL** or **CQL**. The default value is **WQL**. + +```yaml +Type: System.String +Parameter Sets: QueryExpressionSessionSet, QueryExpressionComputerSet +Aliases: + +Required: False +Position: Named +Default value: WQL +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -SourceIdentifier + +Specifies a name for the subscription. The name that you specify must be unique in the current +session. The default value is a GUID that PowerShell assigns. This value appears in the value of the +**SourceIdentifier** property of the subscriber object and of all event objects associated with this +subscription. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -SupportEvent + +Indicates that the event subscription is hidden. Use this parameter when the current subscription is +part of a more complex event registration mechanism and it should not be discovered independently. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### System.Object + +This cmdlet returns an **EventSubscription** object. + +## NOTES + +PowerShell includes the following aliases for `Register-CimIndicationEvent`: + +- Windows: + - `rcie` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-Event](../microsoft.powershell.utility/get-event.md) + +[Remove-Event](../microsoft.powershell.utility/remove-event.md) + +[Unregister-Event](../microsoft.powershell.utility/unregister-event.md) + +[Write-Host](../microsoft.powershell.utility/write-host.md) + +[Get-CimSession](Get-CimSession.md) + +[New-CimSession](New-CimSession.md) diff --git a/reference/7.6/CimCmdlets/Remove-CimInstance.md b/reference/7.6/CimCmdlets/Remove-CimInstance.md new file mode 100644 index 000000000000..1fab959caee1 --- /dev/null +++ b/reference/7.6/CimCmdlets/Remove-CimInstance.md @@ -0,0 +1,334 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/remove-ciminstance?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Remove-CimInstance +--- +# Remove-CimInstance + +## SYNOPSIS +Removes a CIM instance from a computer. + +## SYNTAX + +### CimInstanceComputerSet (Default) + +``` +Remove-CimInstance [-ResourceUri ] [-ComputerName ] [-OperationTimeoutSec ] + [-InputObject] [-WhatIf] [-Confirm] [] +``` + +### CimInstanceSessionSet + +``` +Remove-CimInstance -CimSession [-ResourceUri ] [-OperationTimeoutSec ] + [-InputObject] [-WhatIf] [-Confirm] [] +``` + +### QuerySessionSet + +``` +Remove-CimInstance -CimSession [[-Namespace] ] + [-OperationTimeoutSec ] [-Query] [-QueryDialect ] [-WhatIf] [-Confirm] + [] +``` + +### QueryComputerSet + +``` +Remove-CimInstance [-ComputerName ] [[-Namespace] ] + [-OperationTimeoutSec ] [-Query] [-QueryDialect ] [-WhatIf] [-Confirm] + [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +This cmdlet removes a CIM instance from a CIM server. You can specify the CIM instance to remove by +using either a CIM instance object retrieved by the `Get-CimInstance` cmdlet, or by specifying a +query. + +If the **InputObject** parameter is not specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet works on local Windows Management Instrumentation (WMI) using a Component Object Model + (COM) session. +- If either the **ComputerName** parameter or the **CimSession** parameter is specified, then this + cmdlet works against the CIM server specified by either the **ComputerName** parameter or the + **CimSession** parameter. + +## EXAMPLES + +### Example 1: Remove the CIM instance + +This example use the **Query** parameter to remove CIM instances from the class named +**Win32_Environment** that start with the character string **testvar** . + +```powershell +Remove-CimInstance -Query 'Select * from Win32_Environment where name LIKE "testvar%"' +``` + +### Example 2: Remove the CIM instance using CIM instance object + +This example retrieves the CIM instance objects filtered by the **Query** parameter and stores them +in variable named `$var` using the `Get-CimInstance` cmdlet. The contents of the variable are then +passed to the `Remove-CimInstance` cmdlet, which removes the CIM instances. + +```powershell +notepad.exe +$var = Get-CimInstance -Query 'Select * from Win32_Process where name LIKE "notepad%"' +Remove-CimInstance -InputObject $var +``` + +## PARAMETERS + +### -CimSession + +Runs the command using the specified CIM session. Enter a variable that contains the CIM session, or +a command that creates or gets the CIM session, such as the `New-CimSession` or `Get-CimSession` +cmdlets. For more information, see +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: CimInstanceSessionSet, QuerySessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer on which you want to run the CIM operation. You can specify a +fully qualified domain name (FQDN) or a NetBIOS name. + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WsMan protocol. + +If you do not specify this parameter, the cmdlet performs the operation on the local computer using +Component Object Model (COM). + +If multiple operations are being performed on the same computer, connecting using a CIM session +gives better performance. + +```yaml +Type: System.String[] +Parameter Sets: CimInstanceComputerSet, QueryComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -InputObject + +Specifies a CIM instance object to be removed from the CIM server. The object passed to the cmdlet +is not changed, only the instance in the CIM server is removed. + +The **InputObject** parameter doesn't enumerate over collections. If a collection is passed, an +error is thrown. When working with collections, pipe the input to enumerate the values. + +```yaml +Type: Microsoft.Management.Infrastructure.CimInstance +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet +Aliases: CimInstance + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace for the CIM operation. The default namespace is `root/cimv2`. You can use +tab completion to browse the list of namespaces, because PowerShell gets a list of namespaces from +the local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: False +Position: 2 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value of this parameter is `0`, which means that the cmdlet uses the default timeout value for the +server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Query + +Specifies a query to run on the CIM server. You can specify the query dialect using the +**QueryDialect** parameter. + +If the value specified contains double quotes (`"`), single quotes (`'`), or a backslash (`\`), you +must escape those characters by prefixing them with the backslash (`\`) character. If the value +specified uses the WQL `LIKE` operator, then you must escape the following characters by enclosing +them in square brackets (`[]`): percent (`%`), underscore (`_`), or opening square bracket (`[`). + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -QueryDialect + +Specifies the query language used for the Query parameter. The acceptable values for this parameter +are: `WQL` or `CQL`. The default value is `WQL`. + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: WQL +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ResourceUri + +Specifies the resource uniform resource identifier (URI) of the resource class or instance. The URI +is used to identify a specific type of resource, such as disks or processes, on a computer. + +A URI consists of a prefix and a path to a resource. For example: + +- `http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk` +- `http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings` + +By default, if you do not specify this parameter, the DMTF standard resource URI +`http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/` is used and the class name is appended to it. + +ResourceURI can only be used with CIM sessions created using the WSMan protocol, or when specifying +the ComputerName parameter, which creates a CIM session using WSMan. If you specify this parameter +without specifying the ComputerName parameter, or if you specify a CIM session created using DCOM +protocol, you get an error, because the DCOM protocol does not support the **ResourceURI** +parameter. + +If both the **ResourceUri** parameter and the **Filter** parameter are specified, the **Filter** +parameter is ignored. + +```yaml +Type: System.Uri +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### None + +This cmdlet returns no output. + +## NOTES + +PowerShell includes the following aliases for `Remove-CimInstance`: + +- Windows: + - `rcim` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[New-CimInstance](New-CimInstance.md) + +[Get-CimInstance](get-ciminstance.md) + +[Set-CimInstance](Set-CimInstance.md) diff --git a/reference/7.6/CimCmdlets/Remove-CimSession.md b/reference/7.6/CimCmdlets/Remove-CimSession.md new file mode 100644 index 000000000000..f4ab40c1309c --- /dev/null +++ b/reference/7.6/CimCmdlets/Remove-CimSession.md @@ -0,0 +1,246 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/remove-cimsession?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Remove-CimSession +--- + +# Remove-CimSession + +## SYNOPSIS +Removes one or more CIM sessions. + +## SYNTAX + +### CimSessionSet (Default) + +``` +Remove-CimSession [-CimSession] [-WhatIf] [-Confirm] [] +``` + +### ComputerNameSet + +``` +Remove-CimSession [-ComputerName] [-WhatIf] [-Confirm] [] +``` + +### SessionIdSet + +``` +Remove-CimSession [-Id] [-WhatIf] [-Confirm] [] +``` + +### InstanceIdSet + +``` +Remove-CimSession -InstanceId [-WhatIf] [-Confirm] [] +``` + +### NameSet + +``` +Remove-CimSession -Name [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +The `Remove-CimSession` cmdlet removes one or more CIM session objects from the local PowerShell +session. + +## EXAMPLES + +### Example 1: Remove all the CIM sessions + +This example retrieves all the available CIM sessions on the local computer using the +[Get-CimSession](Get-CimSession.md) cmdlet, and then removes them using the `Remove-CimSession`. + +```powershell +Get-CimSession | Remove-CimSession +``` + +### Example 2: Remove a specific CIM session + +This example removes the CIM session that has an **Id** value of 5. + +```powershell +Remove-CimSession -Id 5 +``` + +### Example 3: Show the list of CIM sessions to remove by using the WhatIf parameter + +This example uses the common parameter **WhatIf** to specify that the removal should not be done, +but only output what would happen if it were done. + +```powershell +Remove-CimSession -Name a* -WhatIf +``` + +## PARAMETERS + +### -CimSession + +Specifies the session objects of the CIM sessions to close. + +Enter a variable that contains the CIM session, or a command that creates or gets the CIM session, +such as the [`New-CimSession`](New-CimSession.md) or [`Get-CimSession`](Get-CimSession.md) cmdlets. +For more information, see +[about_CimSessions](../Microsoft.PowerShell.Core/About/about_CimSession.md). + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: CimSessionSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies an array of names of computers. Removes the sessions that connect to the specified +computers. You can specify a fully qualified domain name (FQDN) or a NetBIOS name. + +```yaml +Type: System.String[] +Parameter Sets: ComputerNameSet +Aliases: CN, ServerName + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### -Id + +Specifies the ID of the CIM session to remove. Specify one or more IDs separated by commas, or use +the range operator (`..`) to specify a range of IDs. An **Id** is an integer that uniquely +identifies the CIM session in the current PowerShell session. + +For more information about the range operator, see [about_Operators](../Microsoft.PowerShell.Core/About/about_Operators.md). + +```yaml +Type: System.UInt32[] +Parameter Sets: SessionIdSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -InstanceId + +Specifies the instance ID of the CIM session to remove. **InstanceId** is a Globally Unique +Identifier (GUID) that uniquely identifies a CIM session. The **InstanceId** is unique, even when +you have multiple sessions running in PowerShell. + +The **InstanceId** is stored in the **InstanceId** property of the object that represents a CIM session. + +```yaml +Type: System.Guid[] +Parameter Sets: InstanceIdSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Name + +Specifies the friendly name of the CIM session to remove. You can use wildcard characters with this +parameter. + +```yaml +Type: System.String[] +Parameter Sets: NameSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: True +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None + +You can't pipe objects to this cmdlet. + +## OUTPUTS + +### System.Object + +This cmdlet returns an object that contains CIM session information. + +## NOTES + +PowerShell includes the following aliases for `Remove-CimSession`: + +- Windows: + - `rcms` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-CimSession](Get-CimSession.md) + +[New-CimSession](New-CimSession.md) + +[about_CimSession](../Microsoft.PowerShell.Core/About/about_CimSession.md) diff --git a/reference/7.6/CimCmdlets/Set-CimInstance.md b/reference/7.6/CimCmdlets/Set-CimInstance.md new file mode 100644 index 000000000000..b405916e3e7a --- /dev/null +++ b/reference/7.6/CimCmdlets/Set-CimInstance.md @@ -0,0 +1,431 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 06/28/2023 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/set-ciminstance?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Set-CimInstance +--- +# Set-CimInstance + +## SYNOPSIS +Modifies a CIM instance on a CIM server by calling the ModifyInstance method of the CIM class. + +## SYNTAX + +### CimInstanceComputerSet (Default) + +``` +Set-CimInstance [-ComputerName ] [-ResourceUri ] [-OperationTimeoutSec ] + [-InputObject] [-Property ] [-PassThru] [-WhatIf] [-Confirm] + [] +``` + +### CimInstanceSessionSet + +``` +Set-CimInstance -CimSession [-ResourceUri ] [-OperationTimeoutSec ] + [-InputObject] [-Property ] [-PassThru] [-WhatIf] [-Confirm] + [] +``` + +### QuerySessionSet + +``` +Set-CimInstance -CimSession [-Namespace ] [-OperationTimeoutSec ] + [-Query] [-QueryDialect ] -Property [-PassThru] [-WhatIf] [-Confirm] + [] +``` + +### QueryComputerSet + +``` +Set-CimInstance [-ComputerName ] [-Namespace ] [-OperationTimeoutSec ] + [-Query] [-QueryDialect ] -Property [-PassThru] [-WhatIf] [-Confirm] + [] +``` + +## DESCRIPTION + +> **This cmdlet is only available on the Windows platform.** + +This cmdlet modifies a CIM instance on a CIM server. + +If the **InputObject** parameter is not specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet works on local Windows Management Instrumentation (WMI) using a Component Object Model + (COM) session. +- If either the **ComputerName** parameter or the **CimSession** parameter is specified, then this + cmdlet works against the CIM server specified by either the **ComputerName** parameter or the + **CimSession** parameter. + +If the **InputObject** parameter is specified, the cmdlet works in one of the following ways: + +- If neither the **ComputerName** parameter nor the **CimSession** parameter is specified, then this + cmdlet uses the CIM session or computer name from the input object. +- If the either the **ComputerName** parameter or the **CimSession** parameter is specified, then + this cmdlet uses the either the **CimSession** parameter value or **ComputerName** parameter + value. This is not very common. + +## EXAMPLES + +### Example 1: Set the CIM instance + +This example sets the value of the **VariableValue** property to **abcd** using the **Query** +parameter. You can modify instances matching a Windows Management Instrumentation Query Language +(WQL) query. + +```powershell +Set-CimInstance -Query 'Select * from Win32_Environment where name LIKE "testvar%"' -Property @{VariableValue="abcd"} +``` + +### Example 2: Set the CIM instance property using pipeline + +This example retrieves the CIM instance object filtered by the **Query** parameter using the +`Get-CimInstance` cmdlet. The `Set-CimInstance` cmdlet modifies the value of **VariableValue** +property to **abcd**. + +```powershell +Get-CimInstance -Query 'Select * from Win32_Environment where name LIKE "testvar%"' | + Set-CimInstance -Property @{VariableValue="abcd"} +``` + +### Example 3: Set the CIM instance property using input object + +```powershell +$x = Get-CimInstance -Query 'Select * from Win32_Environment where Name="testvar"' +Set-CimInstance -InputObject $x -Property @{VariableValue="somevalue"} -PassThru +``` + +This example retrieves the CIM instance objects filtered by the Query parameter in to a variable +`$x` using `Get-CimInstance`, and then passes the contents of the variable to the `Set-CimInstance` +cmdlet. `Set-CimInstance` then modifies the **VariableValue** property to **somevalue**. Because the +**PassThru** parameter is used, This example returns a modified CIM instance object. + +### Example 4: Set the CIM instance property + +This example retrieves the CIM instance object that is specified in the **Query** parameter into a +variable `$x` using the `Get-CimInstance` cmdlet, and changes the **VariableValue** property value +of the object to change. The CIM instance object is then saved using the `Set-CimInstance` cmdlet. +Because the **PassThru** parameter is used, This example returns a modified CIM instance object. + +```powershell +$x = Get-CimInstance -Query 'Select * from Win32_Environment where name="testvar"' +$x.VariableValue = "Change" +Set-CimInstance -CimInstance $x -PassThru +``` + +### Example 5: Show the list of CIM instances to modify using WhatIf + +This example uses the common parameter **WhatIf** to specify that the modification should not be +done, but only output what would happen if it were done. + +```powershell +Set-CimInstance -Query 'Select * from Win32_Environment where name LIKE "testvar%"' -Property @{VariableValue="abcd"} -WhatIf +``` + +### Example 6: Set the CIM instance after confirmation from the user + +This example uses the common parameter **Confirm** to specify that the modification should be done +only after confirmation from the user. + +```powershell +Set-CimInstance -Query 'Select * from Win32_Environment where name LIKE "testvar%"' -Property @{VariableValue="abcd"} -Confirm +``` + +### Example 7: Set the created CIM instance + +This example creates a CIM instance with the specified properties using the `New-CimInstance` +cmdlet, and retrieves its contents in to a variable `$x`. The variable is then passed to the +`Set-CimInstance` cmdlet, which modifies the value of **VariableValue** property to **somevalue**. +Because the **PassThru** parameter is used, This example returns a modified CIM instance object. + +```powershell +$x = New-CimInstance -ClassName Win32_Environment -Property @{Name="testvar";UserName="domain\user"} -Key Name,UserName -ClientOnly +Set-CimInstance -CimInstance $x -Property @{VariableValue="somevalue"} -PassThru +``` + +## PARAMETERS + +### -CimSession + +Runs the cmdlets on a remote computer. Enter a computer name or a session object, such as the output +of a `New-CimSession` or `Get-CimSession` cmdlet. + +```yaml +Type: Microsoft.Management.Infrastructure.CimSession[] +Parameter Sets: CimInstanceSessionSet, QuerySessionSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -ComputerName + +Specifies the name of the computer on which you want to run the CIM operation. You can specify a +fully qualified domain name (FQDN) or a NetBIOS name. + +If you do not specify this parameter, the cmdlet performs the operation on the local computer using +Component Object Model (COM). + +If you specify this parameter, the cmdlet creates a temporary session to the specified computer +using the WsMan protocol. + +If multiple operations are being performed on the same computer, connecting using a CIM session +gives better performance. + +```yaml +Type: System.String[] +Parameter Sets: CimInstanceComputerSet, QueryComputerSet +Aliases: CN, ServerName + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -InputObject + +Specifies a CIM instance object to use as input. + +The **InputObject** parameter doesn't enumerate over collections. If a collection is passed, an +error is thrown. When working with collections, pipe the input to enumerate the values. + +```yaml +Type: Microsoft.Management.Infrastructure.CimInstance +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet +Aliases: CimInstance + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByValue) +Accept wildcard characters: False +``` + +### -Namespace + +Specifies the namespace for the CIM operation. The default namespace is root/cimv2. You can use tab +completion to browse the list of namespaces, because PowerShell gets a list of namespaces from the +local WMI server to provide the list of namespaces. + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. By default, the +value of this parameter is 0, which means that the cmdlet uses the default timeout value for the +server. + +If the **OperationTimeoutSec** parameter is set to a value less than the robust connection retry +timeout of 3 minutes, network failures that last more than the value of the **OperationTimeoutSec** +parameter are not recoverable, because the operation on the server times out before the client can +reconnect. + +```yaml +Type: System.UInt32 +Parameter Sets: (All) +Aliases: OT + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -PassThru + +Returns an object representing the item with which you are working. By default, this cmdlet does not +generate any output. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Property + +Specifies the properties of the CIM instance as a hash table (using name-value pairs). Only the +properties specified using this parameter are changed. Other properties of the CIM instance are not +changed. + +```yaml +Type: System.Collections.IDictionary +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet, QuerySessionSet, QueryComputerSet +Aliases: Arguments + +Required: True (QuerySessionSet, QueryComputerSet), False (CimInstanceComputerSet, CimInstanceSessionSet) +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Query + +Specifies a query to run on the CIM server to retrieve CIM instances on which to run the cmdlet. You +can specify the query dialect using the QueryDialect parameter. + +If the value specified contains double quotes (`"`), single quotes (`'`), or a backslash (`\`), you +must escape those characters by prefixing them with the backslash (`\`) character. If the value +specified uses the WQL **LIKE** operator, then you must escape the following characters by enclosing +them in square brackets (`[]`): percent (`%`), underscore (`_`), or opening square bracket (`[`). + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -QueryDialect + +Specifies the query language used for the Query parameter. The acceptable values for this parameter +are: **WQL** or **CQL**. The default value is **WQL**. + +```yaml +Type: System.String +Parameter Sets: QuerySessionSet, QueryComputerSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -ResourceUri + +Specifies the resource uniform resource identifier (URI) of the resource class or instance. The URI +is used to identify a specific type of resource, such as disks or processes, on a computer. + +A URI consists of a prefix and a path to a resource. For example: + +- `http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/Win32_LogicalDisk` +- `http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings` + +By default, if you do not specify this parameter, the DMTF standard resource URI +`http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/` is used and the class name is appended to it. + +ResourceURI can only be used with CIM sessions created using the WSMan protocol, or when specifying +the ComputerName parameter, which creates a CIM session using WSMan. If you specify this parameter +without specifying the ComputerName parameter, or if you specify a CIM session created using DCOM +protocol, you will get an error, because the DCOM protocol does not support the ResourceURI +parameter. + +If both the **ResourceUri** parameter and the **Filter** parameter are specified, the **Filter** +parameter is ignored. + +```yaml +Type: System.Uri +Parameter Sets: CimInstanceComputerSet, CimInstanceSessionSet +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet is not run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](../Microsoft.PowerShell.Core/About/about_CommonParameters.md). + +## INPUTS + +### Microsoft.Management.Infrastructure.CimInstance + +## OUTPUTS + +### None + +By default, this cmdlet returns no output. + +### Microsoft.Management.Infrastructure.CimInstance + +When you use the **PassThru** parameter, this cmdlet returns the modified CIM instance object. + +## NOTES + +PowerShell includes the following aliases for `Set-CimInstance`: + +- Windows: + - `scim` + +This cmdlet is only available on Windows platforms. + +## RELATED LINKS + +[Get-CimInstance](get-ciminstance.md) + +[New-CimInstance](New-CimInstance.md) + +[Remove-CimInstance](remove-ciminstance.md) diff --git a/reference/7.6/Microsoft.PowerShell.Archive/Compress-Archive.md b/reference/7.6/Microsoft.PowerShell.Archive/Compress-Archive.md new file mode 100644 index 000000000000..6f5b17d46d0b --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Archive/Compress-Archive.md @@ -0,0 +1,464 @@ +--- +external help file: Microsoft.PowerShell.Archive-help.xml +Locale: en-US +Module Name: Microsoft.PowerShell.Archive +ms.date: 03/03/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.archive/compress-archive?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Compress-Archive +--- + +# Compress-Archive + +## SYNOPSIS +Creates a compressed archive, or zipped file, from specified files and directories. + +## SYNTAX + +### Path (Default) + +``` +Compress-Archive [-Path] [-DestinationPath] [-CompressionLevel ] + [-PassThru] [-WhatIf] [-Confirm] [] +``` + +### PathWithUpdate + +``` +Compress-Archive [-Path] [-DestinationPath] [-CompressionLevel ] + -Update [-PassThru] [-WhatIf] [-Confirm] [] +``` + +### PathWithForce + +``` +Compress-Archive [-Path] [-DestinationPath] [-CompressionLevel ] + -Force [-PassThru] [-WhatIf] [-Confirm] [] +``` + +### LiteralPathWithUpdate + +``` +Compress-Archive -LiteralPath [-DestinationPath] [-CompressionLevel ] + -Update [-PassThru] [-WhatIf] [-Confirm] [] +``` + +### LiteralPathWithForce + +``` +Compress-Archive -LiteralPath [-DestinationPath] [-CompressionLevel ] + -Force [-PassThru] [-WhatIf] [-Confirm] [] +``` + +### LiteralPath + +``` +Compress-Archive -LiteralPath [-DestinationPath] [-CompressionLevel ] + [-PassThru] [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +The `Compress-Archive` cmdlet creates a compressed, or zipped, archive file from one or more +specified files or directories. An archive packages multiple files, with optional compression, into +a single zipped file for easier distribution and storage. An archive file can be compressed using +the compression algorithm specified by the **CompressionLevel** parameter. + +The `Compress-Archive` cmdlet uses the **System.IO.Compression.ZipArchive** API to compress files. +The API limits the maximum file size to 2GB. For more information, see +[System.IO.Compression.ZipArchive](xref:System.IO.Compression.ZipArchive). + +> [!NOTE] +> The `Compress-Archive` cmdlet ignores hidden files and folders when creating or updating the +> archive file. On non-Windows machines, this includes files and folders with name that begins with +> the period (`.`) character. +> +> To ensure hidden files and folders are compressed into the archive, use the .NET API instead. + +Some examples use splatting to reduce the line length of the code samples. For more information, see +[about_Splatting](../Microsoft.PowerShell.Core/About/about_Splatting.md). + +## EXAMPLES + +### Example 1: Compress files to create an archive file + +This example compresses files from different directories and creates an archive file. A wildcard is +used to get all files with a particular file extension. There's no directory structure in the +archive file because the **Path** only specifies file names. + +```powershell +$compress = @{ + Path = "C:\Reference\Draftdoc.docx", "C:\Reference\Images\*.vsd" + CompressionLevel = "Fastest" + DestinationPath = "C:\Archives\Draft.zip" +} +Compress-Archive @compress +``` + +The **Path** parameter accepts specific file names and file names with wildcards, `*.vsd`. The +**Path** uses a comma-separated list to get files from different directories. The compression level +is **Fastest** to reduce processing time. The **DestinationPath** parameter specifies the location +for the `Draft.zip` file. The `Draft.zip` file contains `Draftdoc.docx` and all the files with a +`.vsd` extension. + +### Example 2: Compress files using a LiteralPath + +This example compresses specific named files and creates a new archive file. There's no directory +structure in the archive file because the **Path** only specifies file names. + +```powershell +$compress = @{ +LiteralPath= "C:\Reference\Draft Doc.docx", "C:\Reference\Images\diagram2.vsd" +CompressionLevel = "Fastest" +DestinationPath = "C:\Archives\Draft.zip" +} +Compress-Archive @compress +``` + +Absolute path and file names are used because the **LiteralPath** parameter doesn't accept +wildcards. The **Path** uses a comma-separated list to get files from different directories. The +compression level is **Fastest** to reduce processing time. The **DestinationPath** parameter +specifies the location for the `Draft.zip` file. The `Draft.zip` file only contains `Draftdoc.docx` +and `diagram2.vsd`. + +### Example 3: Compress a directory that includes the root directory + +This example compresses a directory and creates an archive file that **includes** the root +directory, and all its files and subdirectories. The archive file has a directory structure because +the **Path** specifies a root directory. + +```powershell +Compress-Archive -Path C:\Reference -DestinationPath C:\Archives\Draft.zip +``` + +`Compress-Archive` uses the **Path** parameter to specify the root directory, `C:\Reference`. The +**DestinationPath** parameter specifies the location for the archive file. The `Draft.zip` archive +includes the `Reference` root directory, and all its files and subdirectories. + +### Example 4: Compress a directory that excludes the root directory + +This example compresses a directory and creates an archive file that **excludes** the root directory +because the **Path** uses an asterisk (`*`) wildcard. The archive contains a directory structure +that contains the root directory's files and subdirectories. + +```powershell +Compress-Archive -Path C:\Reference\* -DestinationPath C:\Archives\Draft.zip +``` + +`Compress-Archive` uses the **Path** parameter to specify the root directory, `C:\Reference` with an +asterisk (`*`) wildcard. The **DestinationPath** parameter specifies the location for the archive +file. The `Draft.zip` archive contains the root directory's files and subdirectories. The +`Reference` root directory is excluded from the archive. + +### Example 5: Compress only the files in a root directory + +This example compresses only the files in a root directory and creates an archive file. There's no +directory structure in the archive because only files are compressed. + +```powershell +Compress-Archive -Path C:\Reference\*.* -DestinationPath C:\Archives\Draft.zip +``` + +`Compress-Archive` uses the **Path** parameter to specify the root directory, `C:\Reference` with a +**star-dot-star** (`*.*`) wildcard. The **DestinationPath** parameter specifies the location for the +archive file. The `Draft.zip` archive only contains the `Reference` root directory's files and the +root directory is excluded. + +### Example 6: Use the pipeline to archive files + +This example sends files down the pipeline to create an archive. There's no directory structure in +the archive file because the **Path** only specifies file names. + +```powershell +Get-ChildItem -Path C:\Reference\Afile.txt, C:\Reference\Images\Bfile.txt | + Compress-Archive -DestinationPath C:\Archives\PipelineFiles.zip +``` + +`Get-ChildItem` uses the **Path** parameter to specify two files from different directories. Each +file is represented by a **FileInfo** object and is sent down the pipeline to `Compress-Archive`. +The two specified files are archived in `PipelineFiles.zip`. + +### Example 7: Use the pipeline to archive a directory + +This example sends a directory down the pipeline to create an archive. Files are sent as +**FileInfo** objects and directories as **DirectoryInfo** objects. The archive's directory structure +doesn't include the root directory, but its files and subdirectories are included in the archive. + +```powershell +Get-ChildItem -Path C:\LogFiles | Compress-Archive -DestinationPath C:\Archives\PipelineDir.zip +``` + +`Get-ChildItem` uses the **Path** parameter to specify the `C:\LogFiles` root directory. Each +**FileInfo** and **DirectoryInfo** object is sent down the pipeline. + +`Compress-Archive` adds each object to the `PipelineDir.zip` archive. The **Path** parameter isn't +specified because the pipeline objects are received into parameter position 0. + +### Example 8: How recursion can affect archives + +This example shows how recursion can duplicate files in your archive. For example, if you use +`Get-ChildItem` with the **Recurse** parameter. As recursion processes, each **FileInfo** and +**DirectoryInfo** object is sent down the pipeline and added to the archive. + +```powershell +Get-ChildItem -Path C:\TestLog -Recurse | + Compress-Archive -DestinationPath C:\Archives\PipelineRecurse.zip +``` + +The `C:\TestLog` directory doesn't contain any files. It does contain a subdirectory named `testsub` +that contains the `testlog.txt` file. + +`Get-ChildItem` uses the **Path** parameter to specify the root directory, `C:\TestLog`. The +**Recurse** parameter processes the files and directories. A **DirectoryInfo** object is created for +`testsub` and a **FileInfo** object `testlog.txt`. + +Each object is sent down the pipeline to `Compress-Archive`. The **DestinationPath** specifies the +location for the archive file. The **Path** parameter isn't specified because the pipeline objects +are received into parameter position 0. + +The following summary describes the `PipelineRecurse.zip` archive's contents that contains a +duplicate file: + +- The **DirectoryInfo** object creates the `testsub` directory and contains the `testlog.txt` file, + which reflects the original directory structure. +- The **FileInfo** object creates a duplicate `testlog.txt` in the archive's root. The duplicate + file is created because recursion sent a file object to `Compress-Archive`. This behavior is + expected because each object sent down the pipeline is added to the archive. + +### Example 9: Update an existing archive file + +This example updates an existing archive file, `Draft.zip`, in the `C:\Archives` directory. In this +example, the existing archive file contains the root directory, and its files and subdirectories. + +```powershell +Compress-Archive -Path C:\Reference -Update -DestinationPath C:\Archives\Draft.zip +``` + +The command updates `Draft.zip` with newer versions of existing files in the `C:\Reference` +directory and its subdirectories. And, new files that were added to `C:\Reference` or its +subdirectories are included in the updated `Draft.zip` archive. + +## PARAMETERS + +### -CompressionLevel + +Specifies how much compression to apply when you're creating the archive file. Faster compression +requires less time to create the file, but can result in larger file sizes. + +If this parameter isn't specified, the command uses the default value, **Optimal**. + +The following are the acceptable values for this parameter: + +- **Fastest**. Use the fastest compression method available to reduce processing time. Faster + compression can result in larger file sizes. +- **NoCompression**. Doesn't compress the source files. +- **Optimal**. Processing time is dependent on file size. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: +Accepted values: Optimal, NoCompression, Fastest + +Required: False +Position: Named +Default value: Optimal +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -DestinationPath + +This parameter is required and specifies the path to the archive output file. The +**DestinationPath** should include the name of the zipped file, and either the absolute or relative +path to the zipped file. + +If the file name in **DestinationPath** doesn't have a `.zip` file name extension, the cmdlet adds +the `.zip` file name extension. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Force + +Use this parameter to overwrite an existing archive file. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: PathWithForce, LiteralPathWithForce +Aliases: + +Required: True +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -LiteralPath + +Specifies the path or paths to the files that you want to add to the archive zipped file. Unlike the +**Path** parameter, the value of **LiteralPath** is used exactly as it's typed. No characters are +interpreted as wildcards. If the path includes escape characters, enclose each escape character in +single quotation marks, to instruct PowerShell not to interpret any characters as escape sequences. +To specify multiple paths, and include files in multiple locations in your output zipped file, use +commas to separate the paths. + +```yaml +Type: System.String[] +Parameter Sets: LiteralPathWithUpdate, LiteralPathWithForce, LiteralPath +Aliases: PSPath + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -PassThru + +Causes the cmdlet to output a file object representing the archive file created. + +This parameter was introduced in PowerShell 6.0. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Path + +Specifies the path or paths to the files that you want to add to the archive zipped file. To specify +multiple paths, and include files in multiple locations, use commas to separate the paths. + +This parameter accepts wildcard characters. Wildcard characters allow you to add all files in a +directory to your archive file. + +Using wildcards with a root directory affects the archive's contents: + +- To create an archive that **includes** the root directory, and all its files and subdirectories, + specify the root directory in the **Path** without wildcards. For example: `-Path C:\Reference` +- To create an archive that **excludes** the root directory, but zips all its files and + subdirectories, use the asterisk (`*`) wildcard. For example: `-Path C:\Reference\*` +- To create an archive that only zips the files in the root directory, use the **star-dot-star** + (`*.*`) wildcard. Subdirectories of the root aren't included in the archive. For example: + `-Path C:\Reference\*.*` + +```yaml +Type: System.String[] +Parameter Sets: Path, PathWithUpdate, PathWithForce +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: True +``` + +### -Update + +Updates the specified archive by replacing older file versions in the archive with newer file +versions that have the same names. You can also add this parameter to add files to an existing +archive. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: PathWithUpdate, LiteralPathWithUpdate +Aliases: + +Required: True +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet isn't run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +You can pipe a string that contains a path to one or more files. + +## OUTPUTS + +### None + +By default, this cmdlet returns no output. + +### System.IO.FileInfo + +When you use the **PassThru** parameter, this cmdlet returns a **FileInfo** object. + +## NOTES + +Using recursion and sending objects down the pipeline can duplicate files in your archive. For +example, if you use `Get-ChildItem` with the **Recurse** parameter, each **FileInfo** and +**DirectoryInfo** object that's sent down the pipeline is added to the archive. + +The `Compress-Archive` cmdlet uses UTF-8 encoding. Other ZIP archive tools may use a different +encoding scheme. When extracting files with filenames not stored using UTF-8 encoding, +`Expand-Archive` uses the raw value found in the archive. This can result in a filename that's +different than the source filename stored in the archive. + +## RELATED LINKS + +[Expand-Archive](Expand-Archive.md) + +[Get-ChildItem](../Microsoft.PowerShell.Management/Get-ChildItem.md) diff --git a/reference/7.6/Microsoft.PowerShell.Archive/Expand-Archive.md b/reference/7.6/Microsoft.PowerShell.Archive/Expand-Archive.md new file mode 100644 index 000000000000..09f8166113e9 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Archive/Expand-Archive.md @@ -0,0 +1,213 @@ +--- +external help file: Microsoft.PowerShell.Archive-help.xml +Locale: en-US +Module Name: Microsoft.PowerShell.Archive +ms.date: 10/06/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: Expand-Archive +--- + +# Expand-Archive + +## SYNOPSIS +Extracts files from a specified archive (zipped) file. + +## SYNTAX + +### Path (Default) + +``` +Expand-Archive [-Path] [[-DestinationPath] ] [-Force] [-PassThru] + [-WhatIf] [-Confirm] [] +``` + +### LiteralPath + +``` +Expand-Archive -LiteralPath [[-DestinationPath] ] [-Force] [-PassThru] + [-WhatIf] [-Confirm] [] +``` + +## DESCRIPTION + +The `Expand-Archive` cmdlet extracts files from a specified zipped archive file to a specified +destination folder. An archive file allows multiple files to be packaged, and optionally compressed, +into a single zipped file for easier distribution and storage. + +## EXAMPLES + +### Example 1: Extract the contents of an archive + +This example extracts the contents of an existing archive file into the folder specified by the +**DestinationPath** parameter. + +```powershell +Expand-Archive -LiteralPath 'C:\Archives\Draft[v1].zip' -DestinationPath C:\Reference +``` + +In this example, the **LiteralPath** parameter is used because the filename contains characters that +could be interpreted as wildcards. + +### Example 2: Extract the contents of an archive in the current folder + +This example extracts the contents of an existing archive file in the current folder into the folder +specified by the **DestinationPath** parameter. + +```powershell +Expand-Archive -Path Draftv2.zip -DestinationPath C:\Reference +``` + +## PARAMETERS + +### -DestinationPath + +By default, `Expand-Archive` creates a folder in the current location that's the same name as the +ZIP file. The parameter allows you to specify the path to a different folder. The target folder is +created if it doesn't exist. + +```yaml +Type: System.String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: A folder in the current location +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Force + +Use this parameter to overwrite existing files. By default, `Expand-Archive` doesn't overwrite. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -LiteralPath + +Specifies the path to an archive file. Unlike the **Path** parameter, the value of **LiteralPath** +is used exactly as it's typed. Wildcard characters aren't supported. If the path includes escape +characters, enclose each escape character in single quotation marks, to instruct PowerShell not to +interpret any characters as escape sequences. + +```yaml +Type: System.String +Parameter Sets: LiteralPath +Aliases: PSPath + +Required: True +Position: Named +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + +### -PassThru + +Causes the cmdlet to output a list of the files expanded from the archive. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Path + +Specifies the path to the archive file. + +```yaml +Type: System.String +Parameter Sets: Path +Aliases: + +Required: True +Position: 0 +Default value: None +Accept pipeline input: True (ByPropertyName, ByValue) +Accept wildcard characters: False +``` + +### -Confirm + +Prompts you for confirmation before running the cmdlet. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: cf + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -WhatIf + +Shows what would happen if the cmdlet runs. The cmdlet isn't run. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: (All) +Aliases: wi + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters + +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, +-InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### System.String + +You can pipe a string that contains a path to an existing archive file. + +## OUTPUTS + +### None + +By default, this cmdlet returns no output. + +### System.IO.FileSystemInfo + +When you use the **PassThru** parameter, this cmdlet returns a list of files that were expanded from +the archive. + +## NOTES + +The `Compress-Archive` cmdlet uses UTF-8 encoding. Other ZIP archive tools may use a different +encoding scheme. When extracting files with filenames not stored using UTF-8 encoding, +`Expand-Archive` uses the raw value found in the archive. This can result in a filename that's +different than the source filename stored in the archive. + +## RELATED LINKS + +[Compress-Archive](compress-archive.md) diff --git a/reference/7.6/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.md b/reference/7.6/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.md new file mode 100644 index 000000000000..42eef7fd68ab --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.md @@ -0,0 +1,26 @@ +--- +Download Help Link: https://aka.ms/powershell75-help +Help Version: 7.6.0.0 +Locale: en-US +Module Guid: eb74e8da-9ae2-482a-a648-e96550fb8733 +Module Name: Microsoft.PowerShell.Archive +ms.date: 06/09/2017 +schema: 2.0.0 +title: Microsoft.PowerShell.Archive +--- + +# Microsoft.PowerShell.Archive Module + +## Description + +This section contains the help topics for the cmdlets that are installed with the PowerShell Microsoft.PowerShell.Archive module. The Archive module contains cmdlets that let you create and extract archive or ZIP files. + +## Microsoft.PowerShell.Archive Cmdlets + +### [Compress-Archive](Compress-Archive.md) + +Creates a compressed archive, or zipped file, from specified files and directories. + +### [Expand-Archive](Expand-Archive.md) + +Extracts files from a specified archive (zipped) file. diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/.markdownlint.yaml b/reference/7.6/Microsoft.PowerShell.Core/About/.markdownlint.yaml new file mode 100644 index 000000000000..cfd0d7fc37b9 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/.markdownlint.yaml @@ -0,0 +1,12 @@ +# About topics have different line length requirements; their text is +# automatically wrapped at 80 characters, so it's preferable to control +# the wrapping here instead. +extends: ../../../../.markdownlint.yaml +MD013: # line-length + code_block_line_length: 74 + code_blocks: true + heading_line_length: 79 + headings: true + line_length: 79 + stern: true + tables: false diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/About.md b/reference/7.6/Microsoft.PowerShell.Core/About/About.md new file mode 100644 index 000000000000..f88e8083564b --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/About.md @@ -0,0 +1,652 @@ +--- +description: About topics cover a range of concepts about PowerShell. +Help Version: 7.6.0.0 +Locale: en-US +ms.date: 01/14/2025 +title: About topics +--- +# About topics + +## Description + +About topics cover a range of concepts about PowerShell. + +## About Topics + +### [about_Alias_Provider](about_Alias_Provider.md) + +Provides access to the PowerShell aliases and the values that they represent. + +### [about_Aliases](about_Aliases.md) + +Describes how to use alternate names for cmdlets and commands in PowerShell. + +### [about_ANSI_Terminals](about_ANSI_Terminals.md) + +Describes the support available for ANSI escape sequences in Windows +PowerShell. + +### [about_Arithmetic_Operators](about_Arithmetic_Operators.md) + +Describes the operators that perform arithmetic in PowerShell. + +### [about_Arrays](about_Arrays.md) + +Describes arrays, which are data structures designed to store collections of +items. + +### [about_Assignment_Operators](about_Assignment_Operators.md) + +Describes how to use operators to assign values to variables. + +### [about_Automatic_Variables](about_Automatic_Variables.md) + +Describes variables that store state information for PowerShell. These +variables are created and maintained by PowerShell. + +### [about_Booleans](about_Booleans.md) + +Describes how boolean expressions are evaluated. + +### [about_Break](about_Break.md) + +Describes the `break` statement, which provides a way to exit the current +control block. + +### [about_Built-in_Functions](about_Built-in_Functions.md) + +Describes the built-in functions in PowerShell. + +### [about_Calculated_Properties](about_Calculated_Properties.md) + +PowerShell provides the ability to dynamically add new properties and alter the +formatting of objects output to the pipeline. + +### [about_Calling_Generic_Methods](about_Calling_Generic_Methods.md) + +Generics let you tailor a method, class, structure, or interface to the precise +data type it acts upon. + +### [about_Case-Sensitivity](about_Case-Sensitivity.md) + +PowerShell is as case-insensitive as possible while preserving case. + +### [about_Character_Encoding](about_Character_Encoding.md) + +Describes how PowerShell uses character encoding for input and output of string +data. + +### [about_CimSession](about_CimSession.md) + +Describes a **CimSession** object and the difference between CIM sessions and +PowerShell sessions. + +### [about_Classes](about_Classes.md) + +Describes how you can use classes to create your own custom types. + +### [about_Classes_Constructors](about_Classes_Constructors.md) + +Describes how to define constructors for PowerShell classes. + +### [about_Classes_Inheritance](about_Classes_Inheritance.md) + +Describes how you can define classes that extend other types. + +### [about_Classes_Methods](about_Classes_Methods.md) + +Describes how to define methods for PowerShell classes. + +### [about_Classes_Properties](about_Classes_Properties.md) + +Describes how to define properties for PowerShell classes. + +### [about_Command_Precedence](about_Command_Precedence.md) + +Describes how PowerShell determines which command to run. + +### [about_Command_Syntax](about_Command_Syntax.md) + +Describes the syntax diagrams that are used in PowerShell. + +### [about_Comments](about_Comments.md) + +Describes how to use PowerShell comments and lists special use cases. + +### [about_Comment_Based_Help](about_Comment_Based_Help.md) + +Describes how to write comment-based help topics for functions and scripts. + +### [about_CommonParameters](about_CommonParameters.md) + +Describes the parameters that can be used with any cmdlet. + +### [about_Comparison_Operators](about_Comparison_Operators.md) + +The comparison operators in PowerShell can either compare two values or filter +elements of a collection against an input value. + +### [about_Continue](about_Continue.md) + +Describes how the `continue` statement immediately returns the program flow to +the top of a program loop, a `switch` statement, or a `trap` statement. + +### [about_Core_Commands](about_Core_Commands.md) + +Lists the cmdlets that are designed for use with PowerShell providers. + +### [about_Data_Files](about_Data_Files.md) + +PowerShell data files are used to store arbitrary data using PowerShell syntax. + +### [about_Data_Sections](about_Data_Sections.md) + +Explains Data sections, which isolate text strings and other read-only data +from script logic. + +### [about_Debuggers](about_Debuggers.md) + +Describes the PowerShell debugger. + +### [about_Do](about_Do.md) + +Runs a statement list one or more times, subject to a `While` or `Until` +condition. + +### [about_Enum](about_Enum.md) + +The `enum` statement is used to declare an enumeration. An enumeration is a +distinct type that consists of a set of named labels called the enumerator +list. + +### [about_Environment_Provider](about_Environment_Provider.md) + +Provides access to the Windows environment variables. + +### [about_Environment_Variables](about_Environment_Variables.md) + +Describes how to access and manage environment variables in PowerShell. + +### [about_Execution_Policies](about_Execution_Policies.md) + +Describes the PowerShell execution policies and explains how to manage them. + +### [about_Experimental_Features](about_Experimental_Features.md) + +The PowerShell provides a mechanism for experimental features to coexist with +existing stable features in the PowerShell engine or in a PowerShell module. + +### [about_FileSystem_Provider](about_FileSystem_Provider.md) + +Provides access to files and directories. + +### [about_For](about_For.md) + +Describes a language command you can use to run statements based on a +conditional test. + +### [about_Foreach](about_Foreach.md) + +Describes a language command you can use to traverse all the items in a +collection of items. + +### [about_Format.ps1xml](about_Format.ps1xml.md) + +The `Format.ps1xml` files in PowerShell define the default display of objects +in the PowerShell console. + +### [about_Function_Provider](about_Function_Provider.md) + +Provides access to the functions defined in PowerShell. + +### [about_Functions_Advanced_Methods](about_Functions_Advanced_Methods.md) + +Describes how functions that specify the `CmdletBinding` attribute can use the +methods and properties that are available to compiled cmdlets. + +### [about_Functions_Advanced_Parameters](about_Functions_Advanced_Parameters.md) + +Explains how to add parameters to advanced functions. + +### [about_Functions_Advanced](about_Functions_Advanced.md) + +Introduces advanced functions that are a way to create cmdlets using scripts. + +### [about_Functions_Argument_Completion](about_Functions_Argument_Completion.md) + +Argument completion is a feature of PowerShell that provide hints, enables +discovery, and speeds up input entry of argument values. + +### [about_Functions_CmdletBindingAttribute](about_Functions_CmdletBindingAttribute.md) + +Describes the attribute that makes a function work like a compiled cmdlet. + +### [about_Functions_OutputTypeAttribute](about_Functions_OutputTypeAttribute.md) + +Describes an attribute that reports the type of object that the function returns. + +### [about_Functions](about_Functions.md) + +Describes how to create and use functions in PowerShell. + +### [about_Group_Policy_Settings](about_Group_Policy_Settings.md) + +Describes the Group Policy settings for PowerShell + +### [about_Hash_Tables](about_Hash_Tables.md) + +Describes how to create, use, and sort hashtables in PowerShell. + +### [about_Hidden](about_Hidden.md) + +Describes the `hidden` keyword, which hides class members from default +`Get-Member` results. + +### [about_History](about_History.md) + +Describes how to get and run commands in the command history. + +### [about_If](about_If.md) + +Describes a language command you can use to run statement lists based on the +results of one or more conditional tests. + +### [about_Intrinsic_Members](about_Intrinsic_Members.md) + +Provides information about PowerShell's intrinsic members that are available to +all PowerShell objects. + +### [about_Job_Details](about_Job_Details.md) + +Provides details about background jobs on local and remote computers. + +### [about_Jobs](about_Jobs.md) + +Provides information about how PowerShell background jobs run a command or +expression in the background without interacting with the current session. + +### [about_Join](about_Join.md) + +Describes how the join operator (-join) combines multiple strings into a single +string. + +### [about_Language_Keywords](about_Language_Keywords.md) + +Describes the keywords in the PowerShell scripting language. + +### [about_Language_Modes](about_Language_Modes.md) + +Explains language modes and their effect on PowerShell sessions. + +### [about_Line_Editing](about_Line_Editing.md) + +Describes how to edit commands at the PowerShell command prompt. + +### [about_Locations](about_Locations.md) + +Describes how to access items from the working location in PowerShell. + +### [about_Logging_Non-Windows](about_Logging_Non-Windows.md) + +PowerShell logs internal operations from the engine, providers, and cmdlets. + +### [about_Logging_Windows](about_Logging_Windows.md) + +PowerShell logs internal operations from the engine, providers, and cmdlets to +the Windows event log. + +### [about_Logical_Operators](about_Logical_Operators.md) + +Describes the operators that connect statements in PowerShell. + +### [about_Member-Access_Enumeration](about_Member-Access_Enumeration.md) + +Describes the automatic enumeration of list collection items when using the +member-access operator. + +### [about_Methods](about_Methods.md) + +Describes how to use methods to perform actions on objects in PowerShell. + +### [about_Module_Manifests](about_Module_Manifests.md) + +Describes the settings and practices for writing module manifest files. + +### [about_Modules](about_Modules.md) + +Explains how to install, import, and use PowerShell modules. + +### [about_Numeric_Literals](about_Numeric_Literals.md) + +This article describes the syntax and usage of numeric values in PowerShell. + +### [about_Object_Creation](about_Object_Creation.md) + +Explains how to create objects in PowerShell. + +### [about_Objects](about_Objects.md) + +Provides essential information about objects in PowerShell. + +### [about_Operator_Precedence](about_Operator_Precedence.md) + +Lists the PowerShell operators in precedence order. + +### [about_Operators](about_Operators.md) + +Describes the operators that are supported by PowerShell. + +### [about_Output_Streams](about_Output_Streams.md) + +Explains the availability and purpose of output streams in PowerShell. + +### [about_PackageManagement](about_PackageManagement.md) + +PackageManagement is an aggregator for software package managers. + +### [about_Parameter_Binding](about_Parameter_Binding.md) + +Parameter binding is the process that PowerShell uses to determine which +parameter set is being used and to associate (bind) values to the parameters of +a command. + +### [about_Parameter_Sets](about_Parameter_Sets.md) + +Describes how to define and use parameter sets in advanced functions. + +### [about_Parameters_Default_Values](about_Parameters_Default_Values.md) + +Describes how to set custom default values for cmdlet parameters and advanced +functions. + +### [about_Parameters](about_Parameters.md) + +Describes how to work with command parameters in PowerShell. + +### [about_Parsing](about_Parsing.md) + +Describes how PowerShell parses commands. + +### [about_Path_Syntax](about_Path_Syntax.md) + +Describes the full and relative path formats in PowerShell. + +### [about_Pipeline_Chain_Operators](about_Pipeline_Chain_Operators.md) + +Describes chaining pipelines with the `&&` and `||` operators in PowerShell. + +### [about_Pipelines](about_Pipelines.md) + +Combining commands into pipelines in the PowerShell + +### [about_PowerShell_Config](about_PowerShell_Config.md) + +Configuration files for PowerShell, replacing Registry configuration. + +### [about_PowerShell_Editions](about_PowerShell_Editions.md) + +Different editions of PowerShell run on different underlying runtimes. + +### [about_Preference_Variables](about_Preference_Variables.md) + +Variables that customize the behavior of PowerShell. + +### [about_Profiles](about_Profiles.md) + +Describes how to create and use a PowerShell profile. + +### [about_Prompts](about_Prompts.md) + +Describes the `Prompt` function and demonstrates how to create a custom +`Prompt` function. + +### [about_Properties](about_Properties.md) + +Describes how to use object properties in PowerShell. + +### [about_Providers](about_Providers.md) + +PowerShell providers provide access to data and components, presented in a +consistent format that resembles a file system drive. + +### [about_PSConsoleHostReadLine](about_PSConsoleHostReadLine.md) + +Explains how to create a customize how PowerShell reads input at the console +prompt. + +### [about_PSCustomObject](about_PSCustomObject.md) + +Explains the differences between the `[psobject]` and `[pscustomobject]` type +accelerators. + +### [about_PSItem](about_PSItem.md) + +The automatic variable that contains the current object in the pipeline object. + +### [about_PSModulePath](about_PSModulePath.md) + +This article the purpose and usage of the `$env:PSModulePath` environment +variable. + +### [about_PSSession_Details](about_PSSession_Details.md) + +Provides detailed information about PowerShell sessions and the role they play +in remote commands. + +### [about_PSSessions](about_PSSessions.md) + +Describes PowerShell sessions (PSSessions) and explains how to establish a +persistent connection to a remote computer. + +### [about_Pwsh](about_Pwsh.md) + +Explains how to use the `pwsh` command-line interface. Displays the +command-line parameters and describes the syntax. + +### [about_Quoting_Rules](about_Quoting_Rules.md) + +Describes rules for using single and double quotation marks in PowerShell. + +### [about_Redirection](about_Redirection.md) + +Explains how to redirect output from PowerShell to text files. + +### [about_Ref](about_Ref.md) + +Describes how to create and use a reference type variable. You can use +reference type variables to permit a function to change the value of a variable +that is passed to it. + +### [about_Registry_Provider](about_Registry_Provider.md) + +Describes teh features and functions of the Registry provider. + +### [about_Regular_Expressions](about_Regular_Expressions.md) + +Describes regular expressions in PowerShell. + +### [about_Remote_Disconnected_Sessions](about_Remote_Disconnected_Sessions.md) + +Explains how to disconnect and reconnect to a PowerShell Session (PSSession). + +### [about_Remote_Jobs](about_Remote_Jobs.md) + +Describes how to run jobs on remote computers. + +### [about_Remote_Output](about_Remote_Output.md) + +Describes how to interpret and format the output of remote commands. + +### [about_Remote_Requirements](about_Remote_Requirements.md) + +Describes the system requirements and configuration requirements for running +remote commands in PowerShell. + +### [about_Remote_Troubleshooting](about_Remote_Troubleshooting.md) + +Describes how to troubleshoot remote operations in PowerShell. + +### [about_Remote_Variables](about_Remote_Variables.md) + +Explains how to use local and remote variables in remote commands. + +### [about_Remote](about_Remote.md) + +Describes how to run remote commands in PowerShell. + +### [about_Requires](about_Requires.md) + +Prevents a script from running without the required elements. + +### [about_Reserved_Words](about_Reserved_Words.md) + +Lists the reserved words that cannot be used as identifiers because they have a +special meaning in PowerShell. + +### [about_Return](about_Return.md) + +Exits the current scope, which can be a function, script, or script block. + +### [about_Run_With_PowerShell](about_Run_With_PowerShell.md) + +Explains how to use the "Run with PowerShell" feature to run a script from a +file system drive. + +### [about_Scopes](about_Scopes.md) + +Explains the concept of scope in PowerShell and shows how to set and change the +scope of elements. + +### [about_Script_Blocks](about_Script_Blocks.md) + +Defines what a script block is and explains how to use script blocks in the +PowerShell programming language. + +### [about_Script_Internationalization](about_Script_Internationalization.md) + +Describes the script internationalization features that make it easy for +scripts to display messages and instructions to users in their user interface +(UI) language. + +### [about_Scripts](about_Scripts.md) + +Describes how to run and write scripts in PowerShell. + +### [about_Session_Configuration_Files](about_Session_Configuration_Files.md) + +Describes session configuration files, which are used in a session +configuration (also known as an "endpoint") to define the environment of +sessions that use the session configuration. + +### [about_Session_Configurations](about_Session_Configurations.md) + +Describes session configurations, which determine the users who can connect to +the computer remotely and the commands they can run. + +### [about_Signing](about_Signing.md) + +Explains how to sign scripts so that they comply with the PowerShell execution +policies. + +### [about_Simplified_Syntax](about_Simplified_Syntax.md) + +Describes easier, more natural-language ways of scripting filters for +collections of objects. + +### [about_Special_Characters](about_Special_Characters.md) + +Describes the special character sequences that control how PowerShell +interprets the next characters in the sequence. + +### [about_Splatting](about_Splatting.md) + +Describes how to use splatting to pass parameters to commands in PowerShell. + +### [about_Split](about_Split.md) + +Explains how to use the Split operator to split one or more strings into +substrings. + +### [about_Switch](about_Switch.md) + +Explains how to use a switch to handle multiple `if` statements. + +### [about_Tab_Expansion](about_Tab_Expansion.md) + +PowerShell provides completions on input to provide hints, enable discovery, +and speed up input entry by pressing the Tab key. + +### [about_Telemetry](about_Telemetry.md) + +Describes the telemetry collected in PowerShell and how to opt-out. + +### [about_Thread_Jobs](about_Thread_Jobs.md) + +Provides information about PowerShell thread-based jobs. A thread job is a type +of background job that runs a command or expression in a separate thread within +the current session process. + +### [about_Throw](about_Throw.md) + +Describes the `throw` keyword that generates a terminating error. + +### [about_Trap](about_Trap.md) + +Describes a keyword that handles a terminating error. + +### [about_Try_Catch_Finally](about_Try_Catch_Finally.md) + +Describes how to use the `try`, `catch`, and `finally` blocks to handle +terminating errors. + +### [about_Type_Accelerators](about_Type_Accelerators.md) + +Describes the Type accelerators available for .NET framework classes + +### [about_Type_Conversion](about_Type_Conversion.md) + +PowerShell has a flexible type system that makes it easier to use. However, you +must understand how it works to avoid unexpected results. + +### [about_Type_Operators](about_Type_Operators.md) + +Describes the operators that work with Microsoft .NET types. + +### [about_Types.ps1xml](about_Types.ps1xml.md) + +Explains how to use `Types.ps1xml` files to extend the types of objects that +are used in PowerShell. + +### [about_Updatable_Help](about_Updatable_Help.md) + +Describes the updatable help system in PowerShell. + +### [about_Update_Notifications](about_Update_Notifications.md) + +Notifies users on startup of PowerShell that a new version of PowerShell has +been released. + +### [about_Using](about_Using.md) + +Allows you to indicate which namespaces are used in the session. + +### [about_Variable_Provider](about_Variable_Provider.md) + +Variable + +### [about_Variables](about_Variables.md) + +Describes how variables store values that can be used in PowerShell. + +### [about_While](about_While.md) + +Describes a language statement that you can use to run a command block based on +the results of a conditional test. + +### [about_Wildcards](about_Wildcards.md) + +Describes how to use wildcard characters in PowerShell. + +### [about_Windows_PowerShell_Compatibility](about_Windows_PowerShell_Compatibility.md) + +Describes the Windows PowerShell Compatibility functionality for PowerShell 7. diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_ANSI_Terminals.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_ANSI_Terminals.md new file mode 100644 index 000000000000..89b6f13d14a0 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_ANSI_Terminals.md @@ -0,0 +1,382 @@ +--- +description: Describes the features of PowerShell that use ANSI escape sequences and the terminal hosts that support them. +Locale: en-US +ms.date: 09/29/2023 +schema: 2.0.0 +title: about_ANSI_terminals +--- +# about_ANSI_Terminals + +## Short description + +Describes the support available for ANSI escape sequences in PowerShell. + +## Long description + +PowerShell has many features that support the use of ANSI escape sequences to +control the rendering of output in the terminal application that's hosting +PowerShell. + +PowerShell 7.2 added a new automatic variable, `$PSStyle`, and changes to the +PowerShell engine to support the output of ANSI-decorated text. + +## ANSI Terminal support + +The ANSI features are designed to be compatible with the xterm-based terminals. +For more information, see [xterm][05] in Wikipedia. + +On Windows 10 and higher, the Windows Console Host is xterm compatible. The +[Windows Terminal][06] application is also xterm compatible. + +On macOS, the default terminal application is xterm compatible. + +For Linux, each distribution ships with a different terminal application. +Consult the documentation for your distribution to find a suitable terminal +application. + +## $PSStyle + +The variable has the following properties: + +- **Reset** - Turns off all decorations +- **Blink** - Turns Blink on +- **BlinkOff** - Turns Blink off +- **Bold** - Turns Bold on +- **BoldOff** - Turns Bold off +- **Dim** - Turns Dim on (added in PowerShell 7.4) +- **DimOff** - Turns Dim off (added in PowerShell 7.4) +- **Hidden** - Turns Hidden on +- **HiddenOff** - Turns Hidden off +- **Reverse** - Turns Reverse on +- **ReverseOff** - Turns Reverse off +- **Italic** - Turns Italic on +- **ItalicOff** - Turns Italic off +- **Underline** - Turns underlining on +- **UnderlineOff** - Turns underlining off +- **Strikethrough** - Turns strike through on +- **StrikethroughOff** - Turns strike through off +- **OutputRendering** - Control when output rendering is used +- **Formatting** - Nested object that controls default formatting for output + streams +- **Progress** - Nested object that controls the rendering of progress bars +- **FileInfo** - Nested object to control the coloring of **FileInfo** objects. +- **Foreground** - Nested object to control foreground coloring +- **Background** - Nested object to control background coloring + +The base members return strings of ANSI escape sequences mapped to their names. +The values are settable to allow customization. For example, you could change +bold to underlined. The property names makes it easier for you to create +decorated strings using tab completion: + +```powershell +"$($PSStyle.Background.BrightCyan)Power$($PSStyle.Underline)$($PSStyle.Bold)Shell$($PSStyle.Reset)" +``` + +The following members control how or when ANSI formatting is used: + +- `$PSStyle.OutputRendering` is a + `System.Management.Automation.OutputRendering` enum with the values: + + - `ANSI`: ANSI escape sequences are always passed through as-is. + + > [!IMPORTANT] + > You should use **ANSI** mode when redirecting output to a file or the + > pipeline that's intended to be executed downstream. This ensures that + > the output isn't altered. Using any other mode alters the output by + > removing ANSI escape sequences, which may change the execution behavior. + + - `PlainText`: ANSI escape sequences are always stripped so that it's only + plain text. In remote sessions, if the remote host is set to `PlainText`, + the output is stripped of ANSI escape sequences before sending it back to + the local client. + - `Host`: This is the default behavior. The ANSI escape sequences are removed + from redirected or piped output. For more information, see + [Redirecting output][02]. + +- The `$PSStyle.Background` and `$PSStyle.Foreground` members are strings that + contain the ANSI escape sequences for the 16 standard console colors. + + - `Black` + - `BrightBlack` + - `White` + - `BrightWhite` + - `Red` + - `BrightRed` + - `Magenta` + - `BrightMagenta` + - `Blue` + - `BrightBlue` + - `Cyan` + - `BrightCyan` + - `Green` + - `BrightGreen` + - `Yellow` + - `BrightYellow` + + The values are settable and can contain any number of ANSI escape sequences. + There is also a `FromRgb()` method to specify 24-bit color. There are two + ways to call the `FromRgb()` method. + + ```csharp + string FromRgb(byte red, byte green, byte blue) + string FromRgb(int rgb) + ``` + + Either of the following examples set the background color the 24-bit color + `Beige`. + + ```powershell + $PSStyle.Background.FromRgb(245, 245, 220) + $PSStyle.Background.FromRgb(0xf5f5dc) + ``` + +- `$PSStyle.Formatting` is a nested object to control default formatting of + debug, error, verbose, warning messages, and list and table headers. You can + also control attributes like bolding and underlining. It replaces + `$Host.PrivateData` as the way to manage colors for formatting rendering. + `$Host.PrivateData` continues to exist for backwards compatibility but isn't + connected to `$PSStyle.Formatting`. `$PSStyle.Formatting` has the following + members: + + - **FormatAccent** - formatting for list items + - **ErrorAccent** - formatting for error metadata + - **Error** - formatting for error messages + - **Warning** - formatting for warning messages + - **Verbose** - formatting for verbose messages + - **Debug** - formatting for debug messages + - **TableHeader** - formatting for table headers + - **CustomTableHeaderLabel** - formatting for table headers that are not + actually properties on the object + - **FeedbackName** - formatting for the feedback provider name (added as an + experimental feature in PowerShell 7.4) + - **FeedbackText** - formatting for feedback messages (added as an + experimental feature in PowerShell 7.4) + - **FeedbackAction** - formatting for the feedback provider suggested actions + (added as an experimental feature in PowerShell 7.4) + +- `$PSStyle.Progress` allows you to control progress view bar rendering. + + - **Style** - An ANSI string setting the rendering style. + - **MaxWidth** - Sets the max width of the view. Defaults to `120`. + The minimum value is 18. + - **View** - An enum with values, `Minimal` and `Classic`. `Classic` is the + existing rendering with no changes. `Minimal` is a single line minimal + rendering. `Minimal` is the default. + - **UseOSCIndicator** - Defaults to `$false`. Set this to `$true` for + terminals that support OSC indicators. + + > [!NOTE] + > If the host doesn't support Virtual Terminal, `$PSStyle.Progress.View` is + > automatically set to `Classic`. + + The following example sets the rendering style to a minimal progress bar. + + ```powershell + $PSStyle.Progress.View = 'Minimal' + ``` + +- `$PSStyle.FileInfo` is a nested object to control the coloring of + **FileInfo** objects. + + - **Directory** - Built-in member to specify color for directories + - **SymbolicLink** - Built-in member to specify color for symbolic links + - **Executable** - Built-in member to specify color for executables. + - **Extension** - Use this member to define colors for different file + extensions. The **Extension** member pre-includes extensions for archive + and PowerShell files. + +## Cmdlets that generate ANSI output + +- The markdown cmdlets - the [Show-Markdown][11] cmdlet displays the contents + of a file containing markdown text. The output is rendered using ANSI + sequences to represent different styles. You can manage the definitions of + the styles using the [Get-MarkdownOption][08] and [Set-MarkdownOption][10] + cmdlets. +- PSReadLine cmdlets - the PSReadLine module uses ANSI sequences to colorize + PowerShell syntax elements on the command line. The colors can be managed + using [Get-PSReadLineOption][13] and [Set-PSReadLineOption][14]. +- `Get-Error` - the [Get-Error][07] cmdlet returns a detailed view of an + **Error** object, formatted to make it easier to read. +- `Select-String` - Beginning with PowerShell 7.0, [Select-String][09] uses + ANSI sequences to highlight the matching patterns in the output. +- `Write-Progress` - ANSI output is managed using `$PSStyle.Progress`, as + described above. For more information, see [Write-Progress][12] + +## Redirecting output in `Host` mode + +By default, `$PSStyle.OutputRendering` is a set to **Host**. The ANSI escape +sequences are removed from redirected or piped output. + +**OutputRendering** only applies to rendering in the Host, `Out-File`, and +`Out-String`. Output from native executables isn't affected. + +PowerShell 7.2.6 changed the behavior of `Out-File` and `Out-String` for the +following scenarios: + +- When the input object is pure string, these cmdlets keep the string unchanged + regardless of the **OutputRendering** setting. +- When the input object needs to have a formatting view applied to it, these + cmdlets keep or remove escape sequences from the formatting output strings + based on the **OutputRendering** setting. + +This is a breaking change in these cmdlets compared to PowerShell 7.2. + +**OutputRendering** doesn't apply to output from the PowerShell host process, +for example when you run `pwsh` from a command line and redirect the output. + +In the following example, PowerShell is run on Linux from `bash`. The +`Get-ChildItem` cmdlet produces ANSI-decorated text. Since redirection occurs +in the `bash` process, outside of the PowerShell host, the output isn't +affected by **OutputRendering**. + +```bash +pwsh -noprofile -command 'Get-ChildItem' > out.txt +``` + +When you inspect the contents of `out.txt` you see the ANSI escape sequences. + +By contrast, when redirection occurs within the PowerShell session, +**OutputRendering** affects the redirected output. + +```bash +pwsh -noprofile -command 'Get-ChildItem > out.txt' +``` + +When you inspect the contents of `out.txt` there are no ANSI escape sequences. + +## Disabling ANSI output + +Support for ANSI escape sequences can be turned off using the **TERM** or +**NO_COLOR** environment variables. + +The following values of `$env:TERM` change the behavior as follows: + +- `dumb` - sets `$Host.UI.SupportsVirtualTerminal = $false` +- `xterm-mono` - sets `$PSStyle.OutputRendering = PlainText` +- `xtermm` - sets `$PSStyle.OutputRendering = PlainText` + +If `$env:NO_COLOR` exists, then `$PSStyle.OutputRendering` is set to +**PlainText**. For more information about the **NO_COLOR** environment +variable, see [https://no-color.org/][04]. + +## Using `$PSStyle` from C\# + +C# developers can access `PSStyle` as a singleton, as shown in the following +example: + +```csharp +string output = $"{PSStyle.Instance.Foreground.Red}{PSStyle.Instance.Bold}Hello{PSStyle.Instance.Reset}"; +``` + +`PSStyle` exists in the System.Management.Automation namespace. + +The PowerShell engine includes the following changes: + +- The PowerShell formatting system is updated to respect + `$PSStyle.OutputRendering`. +- The `StringDecorated` type is added to handle ANSI escaped strings. +- The `string IsDecorated` boolean property was added to return **true** when + the string contains `ESC` or `C1 CSI` character sequences. +- The `Length` property of a string returns the length for the text without the + ANSI escape sequences. +- The `StringDecorated Substring(int contentLength)` method returns a substring + starting at index 0 up to the content length that'sn't a part of ANSI escape + sequences. This is needed for table formatting to truncate strings and + preserve ANSI escape sequences that don't take up printable character space. +- The `string ToString()` method stays the same and returns the plaintext + version of the string. +- The `string ToString(bool Ansi)` method returns the raw ANSI embedded string + if the `Ansi` parameter is **true**. Otherwise, a plaintext version with ANSI + escape sequences removed is returned. +- The `FormatHyperlink(string text, uri link)` method returns a string + containing ANSI escape sequences used to decorate hyperlinks. Some terminal + hosts, like the [Windows Terminal][06], support this markup, which makes the + rendered text clickable in the terminal. + +## Static methods of the PSStyle class + +PowerShell 7.4 adds three new static methods to the +`[System.Management.Automation.PSStyle]` class. + +```powershell +[System.Management.Automation.PSStyle] | Get-Member -Static -MemberType Method +``` + +```Output + TypeName: System.Management.Automation.PSStyle + +Name MemberType Definition +---- ---------- ---------- +Equals Method static bool Equals(System.Object objA, System.Object objB) +MapBackgroundColorToEscapeSequence Method static string MapBackgroundColorToEscapeSequence(System.ConsoleColor bac… +MapColorPairToEscapeSequence Method static string MapColorPairToEscapeSequence(System.ConsoleColor foregroun… +MapForegroundColorToEscapeSequence Method static string MapForegroundColorToEscapeSequence(System.ConsoleColor for… +ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object objB) +``` + +These methods provide a way to convert **ConsoleColor** values to ANSI escape +sequences for foreground and background colors or for a combination of both. + +The following examples show the ANSI escape sequences produced by these +methods. + +```powershell +using namespace System.Management.Automation +[PSStyle]::MapBackgroundColorToEscapeSequence('Black') | Format-Hex +``` + +```Output + Label: String (System.String) <3A04954D> + + Offset Bytes Ascii + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + ------ ----------------------------------------------- ----- +0000000000000000 1B 5B 34 30 6D �[40m +``` + +```powershell +[PSStyle]::MapForegroundColorToEscapeSequence('Red') | Format-Hex +``` + +```Output + Label: String (System.String) <38B50F41> + + Offset Bytes Ascii + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + ------ ----------------------------------------------- ----- +0000000000000000 1B 5B 39 31 6D �[91m +``` + +```powershell +[PSStyle]::MapColorPairToEscapeSequence('Red','Black') | Format-Hex +``` + +```Output + Label: String (System.String) <365A5875> + + Offset Bytes Ascii + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + ------ ----------------------------------------------- ----- +0000000000000000 1B 5B 39 31 3B 34 30 6D �[91;40m +``` + +## See also + +- [about_Experimental_Features][03] +- [Using Experimental Features][01] + + +[01]: /powershell/scripting/learn/experimental-features +[02]: #redirecting-output-in-host-mode +[03]: about_Experimental_Features.md +[04]: https://no-color.org/ +[05]: https://wikipedia.org/wiki/Xterm +[06]: https://www.microsoft.com/p/windows-terminal/9n0dx20hk701 +[07]: xref:Microsoft.PowerShell.Utility.Get-Error +[08]: xref:Microsoft.PowerShell.Utility.Get-MarkdownOption +[09]: xref:Microsoft.PowerShell.Utility.Select-String +[10]: xref:Microsoft.PowerShell.Utility.Set-MarkdownOption +[11]: xref:Microsoft.PowerShell.Utility.Show-Markdown +[12]: xref:Microsoft.PowerShell.Utility.Write-Progress +[13]: xref:PSReadLine.Get-PSReadLineOption +[14]: xref:PSReadLine.Set-PSReadLineOption diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Alias_Provider.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Alias_Provider.md new file mode 100644 index 000000000000..25041abb4868 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Alias_Provider.md @@ -0,0 +1,328 @@ +--- +description: Alias +Locale: en-US +ms.date: 10/18/2018 +no-loc: [Alias, Definition, AllScope, Option, None, Constant, Private] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_alias_provider?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Alias_Provider +--- +# about_Alias_Provider + +## Provider name + +Alias + +## Drives + +`Alias:` + +## Capabilities + +**ShouldProcess** + +## Short description + +Provides access to the PowerShell aliases and the values that they represent. + +## Detailed description + +The PowerShell **Alias** provider lets you get, add, change, clear, and delete +aliases in PowerShell. + +An alias is an alternate name for a cmdlet, function, executable file, +including scripts. PowerShell includes a set of built-in aliases. You can add +your own aliases to the current session and to your PowerShell profile. + +The **Alias** drive is a flat namespace that contains only the alias objects. +The aliases have no child items. + +The **Alias** provider supports the following cmdlets, which are covered +in this article. + +- [Get-Location](xref:Microsoft.PowerShell.Management.Get-Location) +- [Set-Location](xref:Microsoft.PowerShell.Management.Set-Location) +- [Get-Item](xref:Microsoft.PowerShell.Management.Get-Item) +- [New-Item](xref:Microsoft.PowerShell.Management.New-Item) +- [Remove-Item](xref:Microsoft.PowerShell.Management.Remove-Item) +- [Clear-Item](xref:Microsoft.PowerShell.Management.Clear-Item) + +PowerShell includes a set of cmdlets that are designed to view and to change +aliases. When you use **Alias** cmdlets, you do not need to specify the +`Alias:` drive in the name. This article does not cover working with **Alias** +cmdlets. + +- [Export-Alias](xref:Microsoft.PowerShell.Utility.Export-Alias) +- [Get-Alias](xref:Microsoft.PowerShell.Utility.Get-Alias) +- [Import-Alias](xref:Microsoft.PowerShell.Utility.Import-Alias) +- [New-Alias](xref:Microsoft.PowerShell.Utility.New-Alias) +- [Set-Alias](xref:Microsoft.PowerShell.Utility.Set-Alias) + +## Types exposed by this provider + +Each alias is an instance of the +[System.Management.Automation.AliasInfo](/dotnet/api/system.management.automation.aliasinfo) +class. + +## Navigating the Alias drive + +The **Alias** provider exposes its data store in the `Alias:` drive. To work +with aliases, you can change your location to the `Alias:` drive by using the +following command: + +```powershell +Set-Location Alias: +``` + +To return to a file system drive, type the drive name. For example, type: + +```powershell +Set-Location C: +``` + +You can also work with the Alias provider from any other PowerShell drive. To +reference an alias from another location, use the `Alias:` drive name in the +path. + +> [!NOTE] +> PowerShell uses aliases to allow you a familiar way to work with provider +> paths. Commands such as `dir` and `ls` are now aliases on Windows and `dir` +> on Linux and macOS for [Get-ChildItem](xref:Microsoft.PowerShell.Management.Get-ChildItem), +> `cd` is an alias for +> [Set-Location](xref:Microsoft.PowerShell.Management.Set-Location). and `pwd` +> is an alias for +> [Get-Location](xref:Microsoft.PowerShell.Management.Get-Location). + +### Displaying the Contents of the Alias: drive + +This command gets the list of all the aliases when the current location is the +`Alias:` drive. It uses a wildcard character `*` to indicate all the contents +of the current location. + +```powershell +PS Alias:\> Get-Item -Path * +``` + +In the `Alias:` drive, a dot `.`, which represents the current location, and a +wildcard character `*`, which represents all items in the current location, +have the same effect. For example, `Get-Item -Path .` or `Get-Item \*` produce +the same result. + +The Alias provider has no containers, so the above command has the +same effect when used with `Get-ChildItem`. + +```powershell +Get-ChildItem -Path Alias: +``` + +### Get a selected alias + +This command gets the `ls` alias. +Because it includes the path, you can use it in any PowerShell drive. + +```powershell +Get-Item -Path Alias:ls +``` + +If you are in the `Alias:` drive, you can omit the drive name from the path. + +You can also retrieve the definition for an alias by prefixing the provider +path with the dollar sign (`$`). + +```powershell +$Alias:ls +``` + +### Get all aliases for a specific cmdlet + +This command gets a list of the aliases that are associated with the +`Get-ChildItem` cmdlet. It uses the **Definition** property, which stores the +cmdlet name. + +```powershell +Get-Item -Path Alias:* | Where-Object {$_.Definition -eq "Get-ChildItem"} +``` + +## Creating aliases + +### Create an alias from the Alias: drive + +This command creates the `serv` alias for the `Get-Service` cmdlet. Because the +current location is in the `Alias:` drive, the `-Path` parameter is not needed. + +This command also uses the `-Options` dynamic parameter to set the **AllScope** +option on the alias. The `-Options` parameter is available in the `New-Item` +cmdlet only when you are in the `Alias:` drive. The dot (`.`) indicates the +current directory, which is the alias drive. + +``` +PS Alias:\> New-Item -Path . -Name serv -Value Get-Service -Options "AllScope" +``` + +### Create an alias with an absolute path + +You can create an alias for any item that invokes a command. +This command creates the `np` alias for `Notepad.exe`. + +```powershell +New-Item -Path Alias:np -Value c:\windows\notepad.exe +``` + +### Create an alias to a new function + +You can create an alias for any function. You can use this feature to create an +alias that includes both a cmdlet and its parameters. + +The first command creates the `CD32` function, which changes the current +directory to the `System32` directory. The second command creates the `go` +alias for the `CD32` function. + +When the command is complete, you can use either `CD32` or `go` to invoke the +function. + +```powershell +function CD32 {Set-Location -Path c:\windows\system32} +Set-Item -Path Alias:go -Value CD32 +``` + +## Changing aliases + +### Change the options of an alias + +You can use the `Set-Item` cmdlet with the `-Options` dynamic parameter to +change the value of the `-Options` property of an alias. + +This command sets the **AllScope** and **ReadOnly** options for the `dir` +alias. The command uses the `-Options` dynamic parameter of the `Set-Item` +cmdlet. The `-Options` parameter is available in `Set-Item` when you use it +with the **Alias** or **Function** provider. + +```powershell +Set-Item -Path Alias:dir -Options "AllScope,ReadOnly" +``` + +### Change an aliases referenced command + +This command uses the `Set-Item` cmdlet to change the `gp` alias so that it +represents the `Get-Process` cmdlet instead of the `Get-ItemProperty` cmdlet. +The `-Force` parameter is required because the value of the **Options** +property of the `gp` alias is set to `ReadOnly`. Because the command is +submitted from within the `Alias:` drive, the drive is not specified in the +path. + +```powershell +Set-Item -Path gp -Value Get-Process -Force +``` + +The change affects the four properties that define the association between the +alias and the command. To view the effect of the change, type the following +command: + +```powershell +Get-Item -Path gp | Format-List -Property * +``` + +### Rename an alias + +This command uses the `Rename-Item` cmdlet to change the `popd` alias to `pop`. + +```powershell +Rename-Item -Path Alias:popd -NewName pop +``` + +## Copying an alias + +This command copies the `pushd` alias so that a new `push` alias is created for +the `Push-Location` cmdlet. + +When the new alias is created, its **Description** property has a null value. +And, its **Option** property has a value of `None`. If the command is issued +from within the `Alias:` drive, you can omit the drive name from the value of +the `-Path` parameter. + +```powershell +Copy-Item -Path Alias:pushd -Destination Alias:push +``` + +## Deleting an alias + +This command deletes the `serv` alias from the current session. +You can use this command in any PowerShell drive. + +```powershell +Remove-Item -Path Alias:serv +``` + +This command deletes aliases that begin with "s". It does not delete read-only +aliases. + +```powershell +Clear-Item -Path Alias:s* +``` + +### Delete read-only aliases + +This command deletes all aliases from the current session, except those with a +value of `Constant` for their **Options** property. The `-Force` parameter +allows the command to delete aliases whose **Options** property has a value of +`ReadOnly`. + +```powershell +Remove-Item Alias:* -Force +``` + +## Dynamic parameters + +Dynamic parameters are cmdlet parameters that are added by a PowerShell +provider and are available only when the cmdlet is being used in the +provider-enabled drive. + +### Options [System.Management.Automation.ScopedItemOptions] + +Determines the value of the **Options** property of an alias. + +- **None**: No options. This value is the default. +- **Constant**:The alias cannot be deleted and its properties cannot be + changed. **Constant** is available only when you create an alias. You cannot + change the option of an existing alias to **Constant**. +- **Private**:The alias is visible only in the current scope, not in the child + scopes. +- **ReadOnly**:The properties of the alias cannot be changed except by using + the `-Force` parameter. You can use `Remove-Item` to delete the alias. +- **AllScope**:The alias is copied to any new scopes that are created. + +#### Cmdlets supported + +- [New-Item](xref:Microsoft.PowerShell.Management.New-Item) +- [Set-Item](xref:Microsoft.PowerShell.Management.Set-Item) + +## Using the pipeline + +Provider cmdlets accept pipeline input. You can use the pipeline to simplify +task by sending provider data from one cmdlet to another provider cmdlet. +To read more about how to use the pipeline with provider cmdlets, see the +cmdlet references provided throughout this article. + +## Getting help + +Beginning in Windows PowerShell 3.0, you can get customized help topics for +provider cmdlets that explain how those cmdlets behave in a file system drive. + +To get the help topics that are customized for the file system drive, run a +[Get-Help](xref:Microsoft.PowerShell.Core.Get-Help) command in a file system +drive or use the `-Path` parameter of +[Get-Help](xref:Microsoft.PowerShell.Core.Get-Help) to specify a file system +drive. + +```powershell +Get-Help Get-ChildItem +``` + +```powershell +Get-Help Get-ChildItem -Path alias: +``` + +## See also + +- [about_Aliases](about_Aliases.md) +- [about_Providers](about_Providers.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Aliases.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Aliases.md new file mode 100644 index 000000000000..510b3c722109 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Aliases.md @@ -0,0 +1,275 @@ +--- +description: Describes how to use alternate names for cmdlets and commands in PowerShell. +Locale: en-US +ms.date: 11/27/2017 +no-loc: [Authenticode, Alias] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_aliases?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Aliases +--- +# about_Aliases + +## Short description + +Describes how to use alternate names for cmdlets and commands in PowerShell. + +## Long description + +An alias is an alternate name or nickname for a cmdlet or for a command +element, such as a function, script, file, or executable file. You can use the +alias instead of the command name in any PowerShell commands. + +To create an alias, use the `New-Alias` cmdlet. For example, the following +command creates the `gas` alias for the `Get-AuthenticodeSignature` cmdlet: + +```powershell +New-Alias -Name gas -Value Get-AuthenticodeSignature +``` + +After you create the alias for the cmdlet name, you can use the alias instead +of the cmdlet name. For example, to get the Authenticode signature for the +`SqlScript.ps1` file, type: + +```powershell +Get-AuthenticodeSignature SqlScript.ps1 +``` + +Or, type: + +```powershell +gas SqlScript.ps1 +``` + +If you create `word` as the alias for Microsoft Office Word, you can type +"word" instead of the following: + +```powershell +"C:\Program Files\Microsoft Office\Office11\Winword.exe" +``` + +## Built-in aliases + +PowerShell includes a set of built-in aliases, including `cd` and `chdir` for +the `Set-Location` cmdlet, `ls` and `dir` on Windows and `dir` on Linux and +macOS for the `Get-ChildItem` cmdlet. + +To get all the aliases on the computer, including the built-in aliases, type: + +```powershell +Get-Alias +``` + +## Alias cmdlets + +PowerShell includes the following cmdlets, which are designed for working with +aliases: + +- `Get-Alias` - Gets all the aliases in the current session. +- `New-Alias` - Creates a new alias. +- `Set-Alias` - Creates or changes an alias. +- `Remove-Alias` - Deletes an alias. +- `Export-Alias` - Exports one or more aliases to a file. +- `Import-Alias` - Imports an alias file into PowerShell. + +For detailed information about the cmdlets, type: + +```powershell +Get-Help -Detailed +``` + +For example, type: + +```powershell +Get-Help Export-Alias -Detailed +``` + +## Creating an alias + +To create a new alias, use the `New-Alias` cmdlet. For example, to create the +`gh` alias for `Get-Help`, type: + +```powershell +New-Alias -Name gh -Value Get-Help +``` + +You can use the alias in commands, just as you would use the full cmdlet name, +and you can use the alias with parameters. + +For example, to get detailed Help for the `Get-CimInstance` cmdlet, type: + +```powershell +Get-Help Get-CimInstance -Detailed +``` + +Or, type: + +```powershell +gh Get-CimInstance -Detailed +``` + +## Saving aliases + +The aliases that you create are saved only in the current session. To use the +aliases in a different session, add the alias to your PowerShell profile. Or, +use the `Export-Alias` cmdlet to save the aliases to a file. + +For more information, type: + +```powershell +Get-Help about_Profiles +``` + +## Getting aliases + +To get all the aliases in the current session, including the built-in aliases, +the aliases in your PowerShell profiles, and the aliases that you have created +in the current session, type: + +```powershell +Get-Alias +``` + +To get particular aliases, use the Name parameter of the `Get-Alias` cmdlet. For +example, to get aliases that begin with "p", type: + +```powershell +Get-Alias -Name p* +``` + +To get the aliases for a particular item, use the Definition parameter. For +example, to get the aliases for the `Get-ChildItem` cmdlet type: + +```powershell +Get-Alias -Definition Get-ChildItem +``` + +### Get-Alias output + +`Get-Alias` returns only one type of object, an **AliasInfo** object +(**System.Management.Automation.AliasInfo**). The name of aliases that don't +include a hyphen, such as `cd` are displayed in the following format: + +```powershell +Get-Alias ac +``` + +```Output +CommandType Name Version Source +----------- ---- ------- ------ +Alias ac -> Add-Content +``` + +This makes it very quick and easy to get the information that you need. + +The arrow-based alias name format is not used for aliases that include a +hyphen. These are likely to be preferred substitute names for cmdlets and +functions, instead of typical abbreviations or nicknames, and the author might +not want them to be as evident. + +## Alternate names for commands with parameters + +You can assign an alias to a cmdlet, script, function, or executable file. You +cannot assign an alias to a command and its parameters. For example, you can +assign an alias to the `Get-Eventlog` cmdlet, but you cannot assign an alias +to the `Get-Eventlog -LogName System` command. + +You can create a function that includes the command. To create a function, +type the word "function" followed by a name for the function. Type the +command, and enclose it in braces ({}). + +For example, the following command creates the syslog function. This function +represents the `Get-Eventlog -LogName System` command: + +```powershell +function Get-SystemEventlog {Get-Eventlog -LogName System} +Set-Alias -Name syslog -Value Get-SystemEventlog +``` + +You can now type "syslog" instead of the command. And, you can create aliases +for the new function. + +For more information about functions, type: + +```powershell +Get-Help about_Functions +``` + +## Alias objects + +PowerShell aliases are represented by objects that are instances of the +System.Management.Automation.AliasInfo class. For more information about this +type of object, see [AliasInfo Class][aliasinfo] in the PowerShell SDK. + +To view the properties and methods of the alias objects, get the aliases. +Then, pipe them to the `Get-Member` cmdlet. For example: + +```powershell +Get-Alias | Get-Member +``` + +To view the values of the properties of a specific alias, such as the `dir` +alias, get the alias. Then, pipe it to the `Format-List` cmdlet. For example, +the following command gets the `dir` alias. Next, the command pipes the alias +to the `Format-List` cmdlet. Then, the command uses the Property parameter of +`Format-List` with a wildcard character (`*`) to display all the properties of +the `dir` alias. The following command performs these tasks: + +```powershell +Get-Alias -Name dir | Format-List -Property * +``` + +## PowerShell Alias provider + +PowerShell includes the Alias provider. The Alias provider lets you view the +aliases in PowerShell as though they were on a file system drive. + +The Alias provider exposes the Alias: drive. To go into the Alias: drive, +type: + +```powershell +Set-Location Alias: +``` + +To view the contents of the drive, type: + +```powershell +Get-ChildItem +``` + +To view the contents of the drive from another PowerShell drive, begin the +path with the drive name. Include the colon (:). For example: + +```powershell +Get-ChildItem -Path Alias: +``` + +To get information about a particular alias, type the drive name and the alias +name. Or, type a name pattern. For example, to get all the aliases that begin +with "p", type: + +```powershell +Get-ChildItem -Path Alias:p* +``` + +For more information about the PowerShell Alias provider, type: + +```powershell +Get-Help Alias +``` + +## See also + +- [about_Functions](about_Functions.md) +- [about_Profiles](about_Profiles.md) +- [about_Providers](about_Providers.md) +- [Export-Alias](xref:Microsoft.PowerShell.Utility.Export-Alias) +- [Get-Alias](xref:Microsoft.PowerShell.Utility.Get-Alias) +- [Import-Alias](xref:Microsoft.PowerShell.Utility.Import-Alias) +- [New-Alias](xref:Microsoft.PowerShell.Utility.New-Alias) +- [Remove-Alias](xref:Microsoft.PowerShell.Utility.Remove-Alias) +- [Set-Alias](xref:Microsoft.PowerShell.Utility.Set-Alias) +- [Get-PSDrive](xref:Microsoft.PowerShell.Management.Get-PSDrive) +- [Get-PSProvider](xref:Microsoft.PowerShell.Management.Get-PSProvider) + + +[aliasinfo]: /dotnet/api/system.management.automation.aliasinfo diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Arithmetic_Operators.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Arithmetic_Operators.md new file mode 100644 index 000000000000..bf5a74260169 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Arithmetic_Operators.md @@ -0,0 +1,643 @@ +--- +description: Describes the operators that perform arithmetic in PowerShell. +Locale: en-US +ms.date: 04/05/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_arithmetic_operators?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Arithmetic_Operators +--- +# about_Arithmetic_Operators + +## Short description + +Describes the operators that perform arithmetic in PowerShell. + +## Long description + +Arithmetic operators calculate numeric values. You can use one or more +arithmetic operators to add, subtract, multiply, and divide values, and to +calculate the remainder (modulus) of a division operation. + +The addition operator (`+`) and multiplication operator (`*`) also operate on +strings, arrays, and hashtables. The addition operator concatenates the input. +The multiplication operator returns multiple copies of the input. You can even +mix object types in an arithmetic statement. The method that's used to evaluate +the statement is determined by the type of the leftmost object in the +expression. + +Beginning in PowerShell 2.0, all arithmetic operators work on 64-bit numbers. + +Beginning in PowerShell 3.0, the `-shr` (shift-right) and `-shl` (shift-left) +are added to support bitwise arithmetic in PowerShell. The bitwise operators +only work on integer types. + +PowerShell supports the following arithmetic operators: + +- Addition (`+`) - Adds numbers, concatenates strings, arrays, and hash tables + + ```powershell + 6 + 2 # result = 8 + "file" + "name" # result = "filename" + @(1, "one") + @(2.0, "two") # result = @(1, "one", 2.0, "two") + @{"one" = 1} + @{"two" = 2} # result = @{"one" = 1; "two" = 2} + ``` + +- Subtraction (`-`) - Subtracts or negates numbers + + ```powershell + 6 - 2 # result = 4 + - -6 # result = 6 + (Get-Date).AddDays(-1) # Yesterday's date + ``` + +- Multiplication (`*`) - Multiply numbers or copy strings and arrays the + specified number of times + + ```powershell + 6 * 2 # result = 12 + @("!") * 4 # result = @("!","!","!","!") + "!" * 3 # result = "!!!" + ``` + +- Division (`/`) - Divides numbers + + ```powershell + 6 / 2 # result = 3 + ``` + +- Modulus (`%`) - returns the remainder of a division operation. + + ```powershell + 7 % 2 # result = 1 + ``` + +- Bitwise AND (`-band`) + + ```powershell + 5 -band 3 # result = 1 + ``` + +- Bitwise NOT (`-bnot`) + + ```powershell + -bnot 5 # result = -6 + ``` + +- Bitwise OR (`-bor`) + + ```powershell + 5 -bor 0x03 # result = 7 + ``` + +- Bitwise XOR (`-bxor`) + + ```powershell + 5 -bxor 3 # result = 6 + ``` + +- Shifts bits to the left (`-shl`) + + ```powershell + 102 -shl 2 # result = 408 + ``` + +- Shifts bits to the right (`-shr`) + + ```powershell + 102 -shr 2 # result = 25 + ``` + +## Operator precedence + +PowerShell processes arithmetic operators in the following order: + +| Precedence | Operator | Description | +| ---------- | ---------------- | --------------------------------------- | +| 1 | `()` | Parentheses | +| 2 | `-` | For a negative number or unary operator | +| 3 | `*`, `/`, `%` | For multiplication and division | +| 4 | `+`, `-` | For addition and subtraction | +| 5 | `-band`, `-bnot` | For bitwise operations | +| 5 | `-bor`, `-bxor` | For bitwise operations | +| 5 | `-shr`, `-shl` | For bitwise operations | + +PowerShell processes the expressions from left to right according to the +precedence rules. The following examples show the effect of the precedence +rules: + +```powershell +3+6/3*4 # result = 11 +3+6/(3*4) # result = 3.5 +(3+6)/3*4 # result = 12 +``` + +The order in which PowerShell evaluates expressions might differ from other +programming and scripting languages that you have used. The following example +shows a complicated assignment statement. + +```powershell +$a = 0 +$b = @(1,2) +$c = @(-1,-2) + +$b[$a] = $c[$a++] +``` + +In this example, the expression `$a++` is evaluated before `$b[$a]`. Evaluating +`$a++` changes the value of `$a` after it's used in the statement `$c[$a++]`, +but before it's used in `$b[$a]`. The variable `$a` in `$b[$a]` equals `1`, not +`0`. Therefore, the statement assigns a value to `$b[1]`, not `$b[0]`. + +The code above is equivalent to: + +```powershell +$a = 0 +$b = @(1,2) +$c = @(-1,-2) + +$tmp = $c[$a] +$a = $a + 1 +$b[$a] = $tmp +``` + +## Division and rounding + +When the quotient of a division operation is an integer, PowerShell rounds the +value to the nearest integer. When the value is `.5`, it rounds to the nearest +even integer. + +The following example shows the effect of rounding to the nearest even integer. + +```powershell +PS> [int]( 5 / 2 ) # Result is rounded down +2 + +PS> [int]( 7 / 2 ) # Result is rounded up +4 +``` + +You can use the `[Math]` class to get different rounding behavior. + +```powershell +PS> [int][Math]::Round(5 / 2,[MidpointRounding]::AwayFromZero) +3 + +PS> [int][Math]::Ceiling(5 / 2) +3 + +PS> [int][Math]::Floor(5 / 2) +2 +``` + +For more information, see the [Math.Round](/dotnet/api/system.math.round) +method. + +## Type conversion to accommodate result + +PowerShell automatically selects the .NET numeric type that best expresses the +result without losing precision. For example: + +```powershell +2 + 3.1 +(2).GetType().FullName +(2 + 3.1).GetType().FullName +``` + +```output +5.1 +System.Int32 +System.Double +``` + +If the result of an operation is too large for the type, the type of the result +is widened to accommodate the result, as in the following example: + +```powershell +(512MB).GetType().FullName +(512MB * 512MB).GetType().FullName +``` + +```output +System.Int32 +System.Double +``` + +The type of the result isn't always the same as one of the operands. In the +following example, the negative value can't be cast to an unsigned integer, and +the unsigned integer is too large to be cast to `Int32`: + +```powershell +([int32]::minvalue + [uint32]::maxvalue).GetType().FullName +``` + +```output +System.Int64 +``` + +In this example, `Int64` can accommodate both types. + +The `System.Decimal` type is an exception. If either operand has the +**Decimal** type, the result is **Decimal** type. Any result too large for the +**Decimal** value is an error. + +```powershell +PS> [Decimal]::maxvalue +79228162514264337593543950335 + +PS> [Decimal]::maxvalue + 1 +RuntimeException: Value was either too large or too small for a Decimal. +``` + +### Potential loss of precision + +Anytime you have a result that exceeds the range of the type, you risk losing +precision due to type conversion. For example, adding a sufficiently large +`[long]` and `[int]` results in the operands being converted to `[double]`. In +this example, `9223372036854775807` is the maximum value of a `[long]` integer. +Adding to value overflows the range of `[long]`. + +```powershell +PS> (9223372036854775807 + 2).GetType().FullName +System.Double +``` + +Casting the result to `[ulong]` yields an inaccurate result, because the +operands were coerced to `[double]` first. + +```powershell +PS> [ulong](9223372036854775807 + 2) +9223372036854775808 +``` + +Defining the larger value as `[ulong]` first avoids the problem and produces the +correct result. + +```powershell +PS> 9223372036854775807ul + 2 +9223372036854775809 +``` + +However, exceeding the range of `[ulong]` results in a `[double]`. + +```powershell +PS> ([ulong]::MaxValue + 1).GetType().FullName +System.Double +``` + +### Bigint arithmetic + +When you perform arithmetic operations on `[bigint]` numbers, PowerShell uses +converts all operands to `[bigint]`, which results in truncation of non-integer +values. For example, the `[double]` value `1.9` is truncated to `1` when +converted to `[bigint]`. + +```powershell +PS> [bigint]1 / 1.9 +1 +PS> 1 / [bigint]1.9 +1 +``` + +This behavior is different from the behavior of other numeric types. In this +example, an `[int]` divided by a `[double]` results in a `[double]`. Casting +`1.9` to an `[int]` rounds the value up to `2`. + +```powershell +PS> 1 / 1.9 +0.526315789473684 +PS> 1 / [int]1.9 +0.5 +``` + +## Adding and multiplying non numeric types + +You can add numbers, strings, arrays, and hash tables. And, you can multiply +numbers, strings, and arrays. However, you can't multiply hash tables. + +When you add strings, arrays, or hash tables, the elements are concatenated. +When you concatenate collections, such as arrays or hash tables, a new object +is created that contains the objects from both collections. If you try to +concatenate hash tables that have the same key, the operation fails. + +For example, the following commands create two arrays and then add them: + +```powershell +$a = 1,2,3 +$b = "A","B","C" +$a + $b +``` + +```output +1 +2 +3 +A +B +C +``` + +You can also perform arithmetic operations on objects of different types. The +operation that PowerShell performs is determined by the Microsoft .NET type of +the leftmost object in the operation. PowerShell tries to convert all the +objects in the operation to the .NET type of the first object. If it succeeds +in converting the objects, it performs the operation appropriate to the .NET +type of the first object. If it fails to convert any of the objects, the +operation fails. + +The following examples demonstrate the use of the addition and multiplication +operators in operations that include different object types. + +```powershell +$array = 1,2,3 +$red = [ConsoleColor]::Red +$blue = [ConsoleColor]::Blue + +"file" + 16 # result = "file16" +$array + 16 # result = 1,2,3,16 +$array + "file" # result = 1,2,3,"file" +$array * 2 # result = 1,2,3,1,2,3 +"file" * 3 # result = "filefilefile" +$blue + 3 # result = Red +$red - 3 # result = Blue +$blue - $red # result = -3 ++ '123' # result = 123 +``` + +Because the method that's used to evaluate statements is determined by the +leftmost object, addition and multiplication in PowerShell aren't strictly +commutative. For example, `(a + b)` doesn't always equal `(b + a)`, and `(ab)` +doesn't always equal `(ba)`. + +The following examples demonstrate this principle: + +```powershell +PS> "file" + 16 +file16 + +PS> 16 + "file" +InvalidArgument: can't convert value "file" to type "System.Int32". Error: +"Input string wasn't in a correct format." +``` + +Hash tables are a slightly different case. You can add hash tables to another +hash table, as long as, the added hash tables don't have duplicate keys. + +The following example show how to add hash tables to each other. + +```powershell +$hash1 = @{a=1; b=2; c=3} +$hash2 = @{c1="Server01"; c2="Server02"} +$hash1 + $hash2 +``` + +```output +Name Value +---- ----- +c2 Server02 +a 1 +b 2 +c1 Server01 +c 3 +``` + +The following example throws an error because one of the keys is duplicated in +both hash tables. + +```powershell +$hash1 = @{a=1; b=2; c=3} +$hash2 = @{c1="Server01"; c="Server02"} +$hash1 + $hash2 +``` + +```output +OperationStopped: +Line | + 3 | $hash1 + $hash2 + | ~~~~~~~~~~~~~~~ + | Item has already been added. Key in dictionary: 'c' Key being added: 'c' +``` + +Also, you can add a hash table to an array; and, the entire hash table becomes +an item in the array. + +```powershell +$array1 = @(0, "Hello World", [datetime]::Now) +$hash1 = @{a=1; b=2} +$array2 = $array1 + $hash1 +$array2 +``` + +```output +0 +Hello World + +Monday, June 12, 2017 3:05:46 PM + +Key : a +Value : 1 +Name : a + +Key : b +Value : 2 +Name : b +``` + +However, you can't add any other type to a hash table. + +```powershell +$hash1 + 2 +``` + +```output +InvalidOperation: A hash table can only be added to another hash table. +``` + +Although the addition operators are very useful, use the assignment operators +to add elements to hash tables and arrays. For more information see +[about_assignment_operators](about_Assignment_Operators.md). The following +examples use the `+=` assignment operator to add items to an array: + +```powershell +$array = @() +(0..2).foreach{ $array += $_ } +$array +``` + +```output +0 +1 +2 +``` + +## Arithmetic operators and variables + +You can also use arithmetic operators with variables. The operators act on the +values of the variables. The following examples demonstrate the use of +arithmetic operators with variables: + +```powershell +PS> $intA = 6 +PS> $intB = 4 +PS> $intA + $intB +10 + +PS> $a = "Power" +PS> $b = "Shell" +PS> $a + $b +PowerShell +``` + +## Arithmetic operators and commands + +Typically, you use the arithmetic operators in expressions with numbers, +strings, and arrays. However, you can also use arithmetic operators with the +objects that commands return and with the properties of those objects. + +The following examples show how to use the arithmetic operators in expressions +with PowerShell commands: + +```powershell +(Get-Date) + (New-TimeSpan -day 1) +``` + +The parenthesis operator forces the evaluation of the `Get-Date` cmdlet and the +evaluation of the `New-TimeSpan -Day 1` cmdlet expression, in that order. Both +results are then added using the `+` operator. + +```powershell +Get-Process | Where-Object { ($_.ws * 2) -gt 50mb } +``` + +```output +Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName +------- ------ ----- ----- ----- ------ -- ----------- + 1896 39 50968 30620 264 1,572.55 1104 explorer + 12802 78 188468 81032 753 3,676.39 5676 OUTLOOK + 660 9 36168 26956 143 12.20 988 PowerShell + 561 14 6592 28144 110 1,010.09 496 services + 3476 80 34664 26092 234 ...45.69 876 svchost + 967 30 58804 59496 416 930.97 2508 WINWORD +``` + +In the above expression, each process working space (`$_.ws`) is multiplied by +`2`; and, the result, compared against `50mb` to see if it's greater than that. + +## Bitwise operators + +PowerShell supports the standard bitwise operators, including bitwise-AND +(`-band`), the inclusive and exclusive bitwise-OR operators (`-bor` and +`-bxor`), and bitwise-NOT (`-bnot`). + +Beginning in PowerShell 2.0, all bitwise operators work with 64-bit integers. + +Beginning in PowerShell 3.0, the `-shr` (shift-right) and `-shl` (shift-left) +are introduced to support bitwise arithmetic in PowerShell. + +PowerShell supports the following bitwise operators. + +| Operator | Description | Expression | Result | +| -------- | ---------------------- | ------------ | ------ | +| `-band` | Bitwise AND | `10 -band 3` | 2 | +| `-bor` | Bitwise OR (inclusive) | `10 -bor 3` | 11 | +| `-bxor` | Bitwise OR (exclusive) | `10 -bxor 3` | 9 | +| `-bnot` | Bitwise NOT | `-bNot 10` | -11 | +| `-shl` | Shift-left | `102 -shl 2` | 408 | +| `-shr` | Shift-right | `102 -shr 1` | 51 | + +Bitwise operators act on the binary format of a value. For example, the bit +structure for the number 10 is 00001010 (based on 1 byte), and the bit +structure for the number 3 is 00000011. When you use a bitwise operator to +compare 10 to 3, the individual bits in each byte are compared. + +In a bitwise AND operation, the resulting bit's set to 1 only when both input +bits are 1. + +``` +1010 (10) +0011 ( 3) +-------------- bAND +0010 ( 2) +``` + +In a bitwise OR (inclusive) operation, the resulting bit's set to 1 when either +or both input bits are 1. The resulting bit's set to 0 only when both input +bits are set to 0. + +``` +1010 (10) +0011 ( 3) +-------------- bOR (inclusive) +1011 (11) +``` + +In a bitwise OR (exclusive) operation, the resulting bit's set to 1 only when +one input bit's 1. + +``` +1010 (10) +0011 ( 3) +-------------- bXOR (exclusive) +1001 ( 9) +``` + +The bitwise NOT operator is a unary operator that produces the binary +complement of the value. A bit of 1 is set to 0 and a bit of 0 is set to 1. + +For example, the binary complement of 0 is -1, the maximum unsigned integer +(0xFFFFFFFF), and the binary complement of -1 is 0. + +```powershell +-bNot 10 +``` + +```Output +-11 +``` + +``` +0000 0000 0000 1010 (10) +------------------------- bNOT +1111 1111 1111 0101 (-11, 0xFFFFFFF5) +``` + +In a bitwise shift-left operation, all bits are moved "n" places to the left, +where "n" is the value of the right operand. A zero is inserted in the ones +place. + +| Expression | Result | Binary Result | +| ----------- | ------ | ------------- | +| `21 -shl 0` | 21 | 0001 0101 | +| `21 -shl 1` | 42 | 0010 1010 | +| `21 -shl 2` | 84 | 0101 0100 | + +In a bitwise shift-right operation, all bits are moved "n" places to the right, +where "n" is specified by the right operand. The shift-right operator (`-shr`) +copies the sign bit to the left-most place when shifting a signed value. For +unsigned values, a zero is inserted in the left-most position. + +| Expression | Result | Binary | Hex | +| :----------------------: | ----------: | -------------------------------: | ---------: | +| `21 -shr 0` | 21 | 00010101 | 0x15 | +| `21 -shr 1` | 10 | 00001010 | 0x0A | +| `21 -shr 2` | 5 | 00000101 | 0x05 | +| `21 -shr 31` | 0 | 00000000 | 0x00 | +| `21 -shr 32` | 21 | 00010101 | 0x15 | +| `21 -shr 64` | 21 | 00010101 | 0x15 | +| `21 -shr 65` | 10 | 00001010 | 0x0A | +| `21 -shr 66` | 5 | 00000101 | 0x05 | +| `[int]::MaxValue -shr 1` | 1073741823 | 00111111111111111111111111111111 | 0x3FFFFFFF | +| `[int]::MinValue -shr 1` | -1073741824 | 11000000000000000000000000000000 | 0xC0000000 | +| `-1 -shr 1` | -1 | 11111111111111111111111111111111 | 0xFFFFFFFF | +| `(-21 -shr 1)` | -11 | 11111111111111111111111111110101 | 0xFFFFFFF5 | +| `(-21 -shr 2)` | -6 | 11111111111111111111111111111010 | 0xFFFFFFF4 | + +## See also + +- [about_Arrays](about_Arrays.md) +- [about_Hash_Tables](about_Hash_Tables.md) +- [about_Operators](about_Operators.md) +- [about_Assignment_Operators](about_Assignment_Operators.md) +- [about_Comparison_Operators](about_Comparison_Operators.md) +- [about_Variables](about_Variables.md) +- [Get-Date](xref:Microsoft.PowerShell.Utility.Get-Date) +- [New-TimeSpan](xref:Microsoft.PowerShell.Utility.New-TimeSpan) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Arrays.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Arrays.md new file mode 100644 index 000000000000..9d35a55c30f2 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Arrays.md @@ -0,0 +1,1125 @@ +--- +description: Describes arrays, which are data structures designed to store collections of items. +Locale: en-US +ms.date: 01/03/2025 +no-loc: [Count, Length, LongLength, Rank, ForEach, Clear, Default, First, Last, SkipUntil, Until, Split, Tuple] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_arrays?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Arrays +--- +# about_Arrays + +## Short description + +Describes arrays, which are data structures designed to store collections of +items. + +## Long description + +An array is a data structure that's designed to store a collection of items. +The items can be the same type or different types. + +Beginning in Windows PowerShell 3.0, a collection of zero or one object has +some properties of arrays. + +## Creating and initializing an array + +To create and initialize an array, assign multiple values to a variable. The +values stored in the array are delimited with a comma and separated from the +variable name by the assignment operator (`=`). + +For example, to create an array named `$A` that contains the seven numeric +(integer) values of 22, 5, 10, 8, 12, 9, and 80, type: + +```powershell +$A = 22,5,10,8,12,9,80 +``` + +The comma can also be used to initialize a single item array by placing the +comma before the single item. + +For example, to create a single item array named `$B` containing the single +value of 7, type: + +```powershell +$B = ,7 +``` + +You can also create and initialize an array using the range operator (`..`). +The following example creates an array containing the values 5 through 8. + +```powershell +$C = 5..8 +``` + +As a result, `$C` contains four values: 5, 6, 7, and 8. + +When no data type is specified, PowerShell creates each array as an object +array (**System.Object[]**). To determine the data type of an array, use the +`GetType()` method. For example: + +```powershell +$A.GetType() +``` + +To create a strongly typed array, that is, an array that can contain only +values of a particular type, cast the variable as an array type, such as +**string[]**, **long[]**, or **int32[]**. To cast an array, precede the +variable name with an array type enclosed in brackets. For example: + +```powershell +[Int32[]]$ia = 1500, 2230, 3350, 4000 +``` + +As a result, the `$ia` array can contain only integers. + +You can create arrays that are cast to any supported type in the .NET. For +example, the objects that `Get-Process` retrieves to represent processes are of +the **System.Diagnostics.Process** type. To create a strongly typed array of +process objects, enter the following command: + +```powershell +[Diagnostics.Process[]]$zz = Get-Process +``` + +## The array sub-expression operator + +The array sub-expression operator creates an array from the statements inside +it. Whatever the statement inside the operator produces, the operator places it +in an array. Even if there is zero or one object. + +The syntax of the array operator is as follows: + +```syntax +@( ... ) +``` + +You can use the array operator to create an array of zero or one object. For +example: + +```powershell +$a = @("Hello World") +$a.Count +``` + +```Output +1 +``` + +```powershell +$b = @() +$b.Count +``` + +```Output +0 +``` + +The array operator is useful in scripts when you are getting objects, but don't +know how many to expect. For example: + +```powershell +$p = @(Get-Process Notepad) +``` + +For more information about the array sub-expression operator, see +[about_Operators][11]. + +## Accessing and using array elements + +### Reading an array + +You can refer to an array using its variable name. To display all the elements +in the array, invoke the array name. For example, `$a` is an array of the +numbers 0 through 9: + +```powershell +$a +``` + +```Output +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +``` + +You can refer to the elements in an array using an index. Enclose the index +number in brackets. Index values start at `0`. For example, to display the +first element in the `$a` array, type: + +```powershell +$a[0] +``` + +```Output +0 +``` + +To display the third element in the `$a` array, type: + +```powershell +$a[2] +``` + +```Output +2 +``` + +You can retrieve part of the array using a range operator for the index. For +example, to retrieve the second to fifth elements of the array, you would type: + +```powershell +$a[1..4] +``` + +```Output +1 +2 +3 +4 +``` + +Negative numbers count from the end of the array. For example, `-1` refers to +the last element of the array. To display the last three elements of the array, +in index ascending order, type: + +```powershell +$a = 0 .. 9 +$a[-3..-1] +``` + +```Output +7 +8 +9 +``` + +If you type negative indexes in descending order, your output changes. + +```powershell +$a = 0 .. 9 +$a[-1..-3] +``` + +```Output +9 +8 +7 +``` + +However, be cautious when using this notation. The notation cycles from the end +boundary to the beginning of the array. + +```powershell +$a = 0 .. 9 +$a[2..-2] +``` + +```Output +2 +1 +0 +9 +8 +``` + +Also, one common mistake is to assume `$a[0..-2]` refers to all the elements of +the array, except for the last one. It refers to the first, last, and +second-to-last elements in the array. + +You can use the plus operator (`+`) to combine a ranges with a list of elements +in an array. For example, to display the elements at index positions 0, 2, and +4 through 6, type: + +```powershell +$a = 0 .. 9 +$a[0,2+4..6] +``` + +```Output +0 +2 +4 +5 +6 +``` + +Also, to list multiple ranges and individual elements you can use the plus +operator. For example, to list elements zero to two, four to six, and the +element at eighth positional type: + +```powershell +$a = 0..9 +$a[+0..2+4..6+8] +``` + +```Output +0 +1 +2 +4 +5 +6 +8 +``` + +### Iterations over array elements + +You can also use looping constructs, such as `foreach`, `for`, and `while` +loops, to refer to the elements in an array. For example, to use a `foreach` +loop to display the elements in the `$a` array, type: + +```powershell +$a = 0..9 +foreach ($element in $a) { + $element +} +``` + +```Output +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +``` + +The `foreach` loop iterates through the array and returns each value in the +array until reaching the end of the array. + +The `for` loop is useful when you are incrementing counters while examining the +elements in an array. For example, to use a `for` loop to return every other +value in an array, type: + +```powershell +$a = 0..9 +for ($i = 0; $i -le ($a.length - 1); $i += 2) { + $a[$i] +} +``` + +```Output +0 +2 +4 +6 +8 +``` + +You can use a `while` loop to display the elements in an array until a defined +condition is no longer true. For example, to display the elements in the `$a` +array while the array index is less than 4, type: + +```powershell +$a = 0..9 +$i=0 +while($i -lt 4) { + $a[$i] + $i++ +} +``` + +```Output +0 +1 +2 +3 +``` + +## Properties of arrays + +### Count or Length or LongLength + +In PowerShell, arrays have three properties that indicate the number of items +contained in the array. + +- **Count** - This property is the most commonly used property to determine the + number of items in any collection, not just an array. It's an `[Int32]` type + value. In Windows PowerShell 5.1 (and older) **Count** alias property for + **Length**. + +- **Length** - This property is an `[Int32]` type value. This contains the same + value as **Count**. + + > [!NOTE] + > While **Count** and **Length** are equivalent for arrays, **Length** can + > have a different meaning for other types. For example, **Length** for a + > string is the number of characters in the string. But the **Count** + > property is always `1`. + +- **Longlength** - This property is an `[Int64]` type value. Use this property + for arrays containing more than 2,147,483,647 elements. + +```powershell +$a = 0..9 +$a.Count +$a.Length +``` + +```Output +10 +10 +``` + +### Rank + +Returns the number of dimensions in the array. Most arrays in PowerShell have +one dimension, only. Even when you think you are building a multidimensional +array like the following example: + +```powershell +$a = @( + @(0,1), + @("b", "c"), + @(Get-Process) +) + +"`$a rank: $($a.Rank)" +"`$a length: $($a.Length)" +"`$a[2] length: $($a[2].Length)" +"Process `$a[2][1]: $($a[2][1].ProcessName)" +``` + +In this example, you are creating a single-dimensional array that contains +other arrays. This is also known as a _jagged array_. The **Rank** property +proved that this is single-dimensional. To access items in a jagged array, the +indexes must be in separate brackets (`[]`). + +```Output +$a rank: 1 +$a length: 3 +$a[2] length: 348 +Process $a[2][1]: AcroRd32 +``` + +Multidimensional arrays are stored in [row-major order][14]. The following +example shows how to create a truly multidimensional array. + +```powershell +[string[,]]$rank2 = [string[,]]::New(3,2) +$rank2.rank +$rank2.Length +$rank2[0,0] = 'a' +$rank2[0,1] = 'b' +$rank2[1,0] = 'c' +$rank2[1,1] = 'd' +$rank2[2,0] = 'e' +$rank2[2,1] = 'f' +$rank2[1,1] +``` + +```Output +2 +6 +d +``` + +To access items in a multidimensional array, separate the indexes using a comma +(`,`) within a single set of brackets (`[]`). + +Some operations on a multidimensional array, such as replication and +concatenation, require that array to be flattened. Flattening turns the array +into a 1-dimensional array of unconstrained type. The resulting array takes on +all the elements in row-major order. Consider the following example: + +```powershell +$a = "red",$true +$b = (New-Object 'int[,]' 2,2) +$b[0,0] = 10 +$b[0,1] = 20 +$b[1,0] = 30 +$b[1,1] = 40 +$c = $a + $b +$a.GetType().Name +$b.GetType().Name +$c.GetType().Name +$c +``` + +The output shows that `$c` is a 1-dimensional array containing the items from +`$a` and `$b` in row-major order. + +```output +Object[] +Int32[,] +Object[] +red +True +10 +20 +30 +40 +``` + +## Methods of arrays + +### Clear + +Sets all element values to the _default value_ of the array's element type. The +`Clear()` method doesn't reset the size of the array. + +In the following example `$a` is an array of objects. + +```powershell +$a = 1, 2, 3 +$a.Clear() +$a | % { $null -eq $_ } +``` + +```Output +True +True +True +``` + +In this example, `$intA` is explicitly typed to contain integers. + +```powershell +[Int[]] $intA = 1, 2, 3 +$intA.Clear() +$intA +``` + +```Output +0 +0 +0 +``` + +### ForEach() + +Allows to iterate over all elements in the array and perform a given operation +for each element of the array. + +The `ForEach()` method has several overloads that perform different operations. + +```Syntax +ForEach(scriptblock expression) +ForEach(scriptblock expression, object[] arguments) +ForEach(type convertToType) +ForEach(string propertyName) +ForEach(string propertyName, object[] newValue) +ForEach(string methodName) +ForEach(string methodName, object[] arguments) +``` + +#### ForEach(scriptblock expression) + +#### ForEach(scriptblock expression, object[] arguments) + +This method was added in PowerShell v4. + +> [!NOTE] +> The syntax requires the usage of a script block. Parentheses are optional if +> the scriptblock is the only parameter. Also, there must not be a space +> between the method and the opening parenthesis or brace. + +The following example shows how use the `ForEach()` method. In this case the +intent is to generate the square value of the elements in the array. + +```powershell +$a = @(0 .. 3) +$a.ForEach({ $_ * $_}) +``` + +```Output +0 +1 +4 +9 +``` + +Just like the **ArgumentList** parameter of `ForEach-Object`, the `arguments` +parameter allows the passing of an array of arguments to a script block +configured to accept them. + +For more information about the behavior of **ArgumentList**, see +[about_Splatting][12]. + +#### ForEach(type convertToType) + +The `ForEach()` method can be used to cast the elements to a different type; +the following example shows how to convert a list of string dates to +`[DateTime]` type. + +```powershell +("1/1/2017", "2/1/2017", "3/1/2017").ForEach([datetime]) +``` + +```Output + +Sunday, January 1, 2017 12:00:00 AM +Wednesday, February 1, 2017 12:00:00 AM +Wednesday, March 1, 2017 12:00:00 AM +``` + +#### ForEach(string propertyName) + +#### ForEach(string propertyName, object[] newValue) + +The `ForEach()` method can also be used to retrieve, or set property values for +every item in the collection. + +```powershell +# Set all LastAccessTime properties of files to the current date. +(dir 'C:\Temp').ForEach('LastAccessTime', (Get-Date)) +# View the newly set LastAccessTime of all items, and find Unique entries. +(dir 'C:\Temp').ForEach('LastAccessTime') | Get-Unique +``` + +```Output +Wednesday, June 20, 2018 9:21:57 AM +``` + +#### ForEach(string methodName) + +#### ForEach(string methodName, object[] arguments) + +Lastly, `ForEach()` methods can be used to execute a method on every item in +the collection. + +```powershell +("one", "two", "three").ForEach("ToUpper") +``` + +```Output +ONE +TWO +THREE +``` + +Just like the **ArgumentList** parameter of `ForEach-Object`, the `arguments` +parameter allows the passing of an array of values to a script block configured +to accept them. + +> [!NOTE] +> Starting in Windows PowerShell 3.0 retrieving properties and executing +> methods for each item in a collection can also be accomplished using "Methods +> of scalar objects and collections". You can read more about that here +> [about_Methods][10]. + +### Where() + +Allows to filter or select the elements of the array. The script must evaluate +to anything different than: zero (0), empty string, `$false` or `$null` for the +element to show after the `Where()`. For more information about boolean +evaluation, see [about_Booleans][04]. + +There is one definition for the `Where()` method. + +``` +Where(scriptblock expression[, WhereOperatorSelectionMode mode + [, int numberToReturn]]) +``` + +> [!NOTE] +> The syntax requires the usage of a script block. Parentheses are optional if +> the scriptblock is the only parameter. Also, there must not be a space +> between the method and the opening parenthesis or brace. + +The `Expression` is a scriptblock that's required for filtering, the `mode` +optional argument allows additional selection capabilities, and the +`numberToReturn` optional argument allows the ability to limit how many items +are returned from the filter. + +The value of `mode` must be a [WhereOperatorSelectionMode][02] enum value: + +- `Default` (`0`) - Return all items +- `First` (`1`) - Return the first item +- `Last` (`2`) - Return the last item +- `SkipUntil` (`3`) - Skip items until condition is true, return all the remaining + items (including the first item for which the condition is true) +- `Until` (`4`) - Return all items until condition is true +- `Split` (`5`) - Return an array of two elements + - The first element contains matching items + - The second element contains the remaining items + +The following example shows how to select all odd numbers from the array. + +```powershell +(0..9).Where{ $_ % 2 } +``` + +```Output +1 +3 +5 +7 +9 +``` + +The next example shows how to select all non-empty strings. + +```powershell +('hi', '', 'there').Where{ $_ } +``` + +```Output +hi +there +``` + +#### Default + +The `Default` mode filters items using the `Expression` scriptblock. + +If a `numberToReturn` is provided, it specifies the maximum number of items +to return. + +```powershell +# Get the zip files in the current users profile, sorted by LastAccessTime +$Zips = dir $env:userprofile -Recurse '*.zip' | Sort-Object LastAccessTime +# Get the least accessed file over 100MB +$Zips.Where({$_.Length -gt 100MB}, 'Default', 1) +``` + +> [!NOTE] +> Both the `Default` mode and `First` mode return the first +> (`numberToReturn`) items, and can be used interchangeably. + +#### Last + +```powershell +$h = (Get-Date).AddHours(-1) +$logs = dir 'C:\' -Recurse '*.log' | Sort-Object CreationTime +# Find the last 5 log files created in the past hour +$logs.Where({$_.CreationTime -gt $h}, 'Last', 5) +``` + +#### SkipUntil + +The `SkipUntil` mode skips all objects in a collection until an object passes +the script block expression filter. It then returns **ALL** remaining +collection items without testing them. _Only one passing item is tested_. + +This means the returned collection contains both _passing_ and +_non-passing_ items that have _NOT_ been tested. + +The number of items returned can be limited by passing a value to the +`numberToReturn` argument. + +```powershell +$computers = "Server01", "Server02", "Server03", "localhost", "Server04" +# Find the first available online server. +$computers.Where({ Test-Connection $_ }, 'SkipUntil', 1) +``` + +```Output +localhost +``` + +#### Until + +The `Until` mode inverts the `SkipUntil` mode. It returns **ALL** items in a +collection until an item passes the script block expression. Once an item +_passes_ the scriptblock expression, the `Where()` method stops processing +items. + +This means that you receive the first set of _non-passing_ items from the +`Where()` method. _After_ one item passes, the rest are _NOT_ tested or +returned. + +The number of items returned can be limited by passing a value to the +`numberToReturn` argument. + +```powershell +# Retrieve the first set of numbers less than or equal to 10. +(1..50).Where({$_ -gt 10}, 'Until') +# This would perform the same operation. +(1..50).Where({$_ -le 10}) +``` + +```Output +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +``` + +> [!NOTE] +> Both `Until` and `SkipUntil` operate under the premise of NOT testing a batch +> of items. +> +> `Until` returns the items **BEFORE** the first _PASS_. `SkipUntil` returns +> all items **AFTER** the first _pass_, including the first passing item. + +#### Split + +The `Split` mode splits, or groups collection items into two separate +collections. Those that pass the scriptblock expression, and those that do not. + +If a `numberToReturn` is specified, the first collection, contains the +_passing_ items, not to exceed the value specified. + +The remaining objects, even those that _PASS_ the expression filter, are +returned in the second collection. + +```powershell +$running, $stopped = (Get-Service).Where({$_.Status -eq 'Running'}, 'Split') +$running +``` + +```Output +Status Name DisplayName +------ ---- ----------- +Running Appinfo Application Information +Running AudioEndpointBu... Windows Audio Endpoint Builder +Running Audiosrv Windows Audio +... +``` + +```powershell +$stopped +``` + +```Output +Status Name DisplayName +------ ---- ----------- +Stopped AJRouter AllJoyn Router Service +Stopped ALG Application Layer Gateway Service +Stopped AppIDSvc Application Identity +... +``` + +> [!NOTE] +> Both `ForEach()` and `Where()` methods are intrinsic members. For more +> information about intrinsic members, see [about_Intrinsic_Members][08]. + +## Get the members of an array + +To get the properties and methods of an array, such as the **Length** property +and the **SetValue** method, use the **InputObject** parameter of the +`Get-Member` cmdlet. + +When you pipe an array to `Get-Member`, PowerShell sends the items one at a +time and `Get-Member` returns the type of each item in the array (ignoring +duplicates). + +When you use the **InputObject** parameter, `Get-Member` returns the members of +the array. + +For example, the following command gets the members of the `$a` array variable. + +```powershell +Get-Member -InputObject $a +``` + +You can also get the members of an array by typing a comma (`,`) before the +value that's piped to the `Get-Member` cmdlet. The comma makes the array the +second item in an array of arrays. PowerShell pipes the arrays one at a time +and `Get-Member` returns the members of the array. Like the next two examples. + +```powershell +,$a | Get-Member + +,(1,2,3) | Get-Member +``` + +## Manipulating an array + +You can change the elements in an array, add an element to an array, and +combine the values from two arrays into a third array. + +To change the value of a particular element in an array, specify the array name +and the index of the element that you want to change, and then use the +assignment operator (`=`) to specify a new value for the element. For example, +to change the value of the second item in the `$a` array (index position 1) to +10, type: + +```powershell +$a[1] = 10 +``` + +You can also use the **SetValue** method of an array to change a value. The +following example changes the second value (index position 1) of the `$a` array +to 500: + +```powershell +$a.SetValue(500,1) +``` + +You can use the `+=` operator to add an element to an array. The following +example shows how to add an element to the `$a` array. + +```powershell +$a = @(0..4) +$a += 5 +``` + +> [!NOTE] +> When you use the `+=` operator, PowerShell actually creates a new array with +> the values of the original array and the added value. This might cause +> performance issues if the operation is repeated several times or the size of +> the array is too big. + +It isn't easy to delete elements from an array, but you can create a new array +that contains only selected elements of an existing array. For example, to +create the `$t` array with all the elements in the `$a` array except for the +value at index position 2, type: + +```powershell +$t = $a[0,1 + 3..($a.length - 1)] +``` + +To combine two arrays into a single array, use the plus operator (`+`). The +following example creates two arrays, combines them, and then displays the +resulting combined array. + +```powershell +$x = 1,3 +$y = 5,9 +$z = $x + $y +``` + +As a result, the `$z` array contains 1, 3, 5, and 9. + +To delete an array, assign a value of `$null` to the array. The following +command deletes the array in the `$a` variable. + +`$a = $null` + +You can also use the `Remove-Item` cmdlet, but assigning a value of `$null` is +faster, especially for large arrays. + +## Arrays of zero or one + +Beginning in Windows PowerShell 3.0, a scalar types and collection of zero or +one objects has the **Count** and **Length** properties. Also, you can use +array index notation to access the value of a singleton scalar object. This +feature helps you to avoid scripting errors that occur when a command that +expects a collection gets fewer than two items. + +The following example shows that a variable that contains no objects has a +**Count** and **Length** of 0. + +```powershell +PS> $a = $null +PS> $a.Count +0 +PS> $a.Length +0 +``` + +The following example shows that a variable that contains one object has a +**Count** and **Length** of 1. You can also use array indexing to access the +value of the object. + +```powershell +PS> $a = 4 +PS> $a.Count +1 +PS> $a.Length +1 +PS> $a[0] +4 +PS> $a[-1] +4 +``` + +When you run a command that could return a collection or a single object, you +can use array indexing to access the value of the object without having to test +the **Count** or **Length** properties. However, if the result is a single +object (singleton), and that object has a **Count** or **Length** property, the +value of those properties belong to the singleton object and don't represent +the number of items in the collection. + +In the following example, the command returns a single string object. The +**Length** of that string is `4`. + +```powershell +PS> $result = 'one','two','three','four' | Where-Object {$_ -like 'f*'} +PS> $result.GetType().FullName +System.String +PS> $result +four +PS> $result.Count +1 +PS❯ $result.Length +4 +``` + +If you want `$result` to be an array of strings, you need to declare the +variable as an array. + +In this example, `$result` is an array of strings. The **Count** and **Length** +of the array is `1`, and the **Length** of the first element is `4`. + +```powershell +PS> [string[]]$result = 'one','two','three','four' | + Where-Object {$_ -like 'f*'} +PS> $result.GetType().FullName +System.String[] +PS> $result +four +PS> $result.Count +1 +PS> $result.Length +1 +PS> $result[0].Length +4 +``` + +## Indexing support for System.Tuple objects + +PowerShell 6.1 added the support for indexed access of **Tuple** objects, +similar to arrays. For example: + +```powershell +PS> $tuple = [Tuple]::Create(1, 'test') +PS> $tuple[0] +1 +PS> $tuple[1] +test +PS> $tuple[0..1] +1 +test +PS> $tuple[-1] +test +``` + +Unlike arrays and other collection objects, **Tuple** objects are treated as a +single object when passed through the pipeline or by parameters that support +arrays of objects. + +For more information, see [System.Tuple][01]. + +## Indexing .NET types that implement `IDictionary` + +PowerShell doesn't call a type's true indexer for types that implement the +generic `IDictionary` interface. Instead, when given a key, +PowerShell tests for the existence of the key using `TryGetValue()`, which +returns `$null` when the key doesn't exist. + +By contrast, if you call the type's true indexer using `Item()`, the +method throws an exception when the key doesn't exist. + +The following example illustrates the difference. + +```powershell +PS> [Collections.Generic.Dictionary[string, int]]::new()['nosuchkey'] +# No output ($null) + +PS> [Collections.Generic.Dictionary[string, int]]::new().Item('nosuchkey') +GetValueInvocationException: Exception getting "Item": "The given key 'nosuchkey' + was not present in the dictionary." +``` + +## Member-access enumeration + +Starting in PowerShell 3.0, when you use the member-access operator to access a +member that doesn't exist on a list collection, PowerShell automatically +enumerates the items in the collection and attempts to access the specified +member on each item. For more information, see +[about_Member-Access_Enumeration][09]. + +### Examples + +The following example creates two new files and stores the resulting objects in +the array variable `$files`. Since the array object doesn't have the +**LastWriteTime** member, the value of **LastWriteTime** is returned for each +item in the array. + +```powershell +$files = (New-Item -Type File -Force '/temp/t1.txt'), + (New-Item -Force -Type File '/temp/t2.txt') +$files.LastWriteTime +``` + +```Output +Friday, June 25, 2021 1:21:17 PM +Friday, June 25, 2021 1:21:17 PM +``` + +Member-access enumeration enables you to _get_ values from items in a +collection, but not to _set_ values on items in a collection. For example: + +```powershell +$files.LastWriteTime = (Get-Date).AddDays(-1) +``` + +```Output +InvalidOperation: The property 'LastWriteTime' cannot be found on this object. +Verify that the property exists and can be set. +``` + +To set the values you must use a method. + +```powershell +$files.set_LastWriteTime((Get-Date).AddDays(-1)) +$files.LastWriteTime +``` + +```Output +Thursday, June 24, 2021 1:23:30 PM +Thursday, June 24, 2021 1:23:30 PM +``` + +The `set_LastWriteTime()` method is a _hidden_ member of the **FileInfo** +object. The following example shows how to find _hidden_ `set` methods. + +```powershell +$files | Get-Member -Force -Name set_* +``` + +```Output + TypeName: System.IO.FileInfo + +Name MemberType Definition +---- ---------- ---------- +Attributes Property System.IO.FileAttributes Attributes {get;set;} +CreationTime Property datetime CreationTime {get;set;} +CreationTimeUtc Property datetime CreationTimeUtc {get;set;} +IsReadOnly Property bool IsReadOnly {get;set;} +LastAccessTime Property datetime LastAccessTime {get;set;} +LastAccessTimeUtc Property datetime LastAccessTimeUtc {get;set;} +LastWriteTime Property datetime LastWriteTime {get;set;} +LastWriteTimeUtc Property datetime LastWriteTimeUtc {get;set;} +``` + +> [!CAUTION] +> Since the method is executed for each item in the collection, care should be +> taken when calling methods using member enumeration. + +## See also + +- [about_For][05] +- [about_ForEach][06] +- [about_Hash_Tables][07] +- [about_Member-Access_Enumeration][09] +- [about_Operators][11] +- [about_Assignment_Operators][03] +- [about_While][13] + + +[01]: /dotnet/api/system.tuple +[02]: xref:System.Management.Automation.WhereOperatorSelectionMode +[03]: about_Assignment_Operators.md +[04]: about_Booleans.md +[05]: about_For.md +[06]: about_ForEach.md +[07]: about_Hash_Tables.md +[08]: about_Intrinsic_Members.md +[09]: about_Member-Access_Enumeration.md +[10]: about_Methods.md +[11]: about_Operators.md +[12]: about_Splatting.md#splatting-with-arrays +[13]: about_While.md +[14]: https://wikipedia.org/wiki/Row-_and_column-major_order diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Assignment_Operators.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Assignment_Operators.md new file mode 100644 index 000000000000..0496f5b061ec --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Assignment_Operators.md @@ -0,0 +1,893 @@ +--- +description: Describes how to use operators to assign values to variables. +Locale: en-US +ms.date: 01/19/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_assignment_operators?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Assignment_Operators +--- +# about_Assignment_Operators + +## Short description + +Describes how to use operators to assign values to variables. + +## Long description + +Assignment operators assign one or more values to a variable. The equals sign +(`=`) is the PowerShell assignment operator. PowerShell also has the following +_compound_ assignment operators: `+=`, `-=`, `*=`, `%=`, `++`, `--`, `??=`. +Compound assignment operators perform operations on the values before the +assignment. + +## Syntax + +The syntax of the assignment operators is as follows: + +- `` `` `` + +Assignable expressions include variables and properties. The value can be a +single value, an array of values, or a command, expression, or statement. + +The increment and decrement operators are unary operators. Each has prefix and +postfix versions. + +- `` +- `` + +The value of the assignable expression must be a number or it must be +convertible to a number. + +## Using the assignment operator + +Variables are named memory spaces that store values. You store the values in +variables using the assignment operator `=`. The new value can replace the +existing value of the variable, or you can append a new value to the existing +value. For example, the following statement assigns the value PowerShell to the +`$MyShell` variable: + +```powershell +$MyShell = "PowerShell" +``` + +When you assign a value to a variable in PowerShell, the variable is created if +it didn't already exist. For example, the first of the following two assignment +statements creates the `$a` variable and assigns a value of 6 to `$a`. The +second assignment statement assigns a value of 12 to `$a`. The first statement +creates a new variable. The second statement changes only its value: + +```powershell +$a = 6 +$a = 12 +``` + +Variables in PowerShell don't have a specific data type unless you cast them. +When a variable contains only one object, the variable takes the data type of +that object. When a variable contains a collection of objects, the variable has +the **System.Object** data type. Therefore, you can assign any type of object +to the collection. The following example shows that you can add process +objects, service objects, strings, and integers to a variable without +generating an error: + +```powershell +$a = Get-Process +$a += Get-Service +$a += "string" +$a += 12 +``` + +Because the assignment operator `=` has a lower precedence than the pipeline +operator `|`, parentheses aren't required to assign the result of a command +pipeline to a variable. For example, the following command sorts the services +on the computer and then assigns the sorted services to the `$a` variable: + +```powershell +$a = Get-Service | Sort-Object -Property name +``` + +You can also assign the value created by a statement to a variable, as in the +following example: + +```powershell +$a = if ($b -lt 0) { 0 } else { $b } +``` + +This example assigns zero to the `$a` variable if the value of `$b` is less +than zero. It assigns the value of `$b` to `$a` if the value of `$b` isn't +less than zero. + +To assign an array (multiple values) to a variable, separate the values +with commas, as follows: + +```powershell +$a = "apple", "orange", "lemon", "grape" +``` + +To assign a hash table to a variable, use the standard hash table notation in +PowerShell. Type an at sign `@` followed by key/value pairs that are separated +by semicolons `;` and enclosed in braces `{ }`. For example, to assign a +hashtable to the `$a` variable, type: + +```powershell +$a = @{one=1; two=2; three=3} +``` + +To assign hexadecimal values to a variable, precede the value with `0x`. +PowerShell converts the hexadecimal value (0x10) to a decimal value (in this +case, 16) and assigns that value to the `$a` variable. For example, to assign a +value of 0x10 to the `$a` variable, type: + +```powershell +$a = 0x10 +``` + +To assign an exponential value to a variable, type the root number, the letter +`e`, and a number that represents a multiple of 10. For example, to assign a +value of 3.1415 to the power of 1,000 to the `$a` variable, type: + +```powershell +$a = 3.1415e3 +``` + +PowerShell can also convert kilobytes `KB`, megabytes `MB`, and gigabytes `GB` +into bytes. For example, to assign a value of 10 kilobytes to the `$a` +variable, type: + +```powershell +$a = 10kb +``` + +## Using compound assignment operators + +Compound assignment operators perform numeric operations on the values before +the assignment. + +> [!IMPORTANT] +> Compound assignment operators don't use dynamic scoping. The variable is +> always in the current scope. + +In the following example, the variable `$x` is defined in the global scope. The +braces create a new scope. The variable `$x` inside the braces is a new +instance and not a copy of the global variable. + +```powershell +$x = 1 # Global scope +& { $x += 1; $x } +``` + +```Output +1 +``` + +When you use the regular assignment operator, you get a copy of the variable +from the parent scope. But notice that `$x` in the parent scope is not changed. + +```powershell +$x = 1 # Global scope +& { $x = $x + 1; $x } +"Global `$x = $x" +``` + +```Output +2 +Global $x = 1 +``` + +### The assignment by addition operator + +The assignment by addition operator `+=` either increments the value of a +variable or appends the specified value to the existing value. The action +depends on whether the variable has a numeric or string type and whether the +variable contains a single value (a scalar) or multiple values (a collection). + +The `+=` operator combines two operations. First, it adds, and then it assigns. +Therefore, the following statements are equivalent: + +```powershell +$a += 2 +$a = ($a + 2) +``` + +When the variable contains a single numeric value, the `+=` operator increments +the existing value by the amount on the right side of the operator. Then, the +operator assigns the resulting value to the variable. The following example +shows how to use the `+=` operator to increase the value of a variable: + +```powershell +$a = 4 +$a += 2 +$a +``` + +``` +6 +``` + +When the value of the variable is a string, the value on the right side of the +operator is appended to the string, as follows: + +```powershell +$a = "Windows" +$a += " PowerShell" +$a +``` + +```Output +Windows PowerShell +``` + +When the value of the variable is an array, the `+=` operator appends the +values on the right side of the operator to the array. Unless the array is +explicitly typed by casting, you can append any type of value to the array, as +follows: + +```powershell +$a = 1,2,3 +$a += 2 +$a +``` + +```Output +1 +2 +3 +2 +``` + +and + +```powershell +$a += "String" +$a +``` + +```Output +1 +2 +3 +2 +String +``` + +When the value of a variable is a hash table, the `+=` operator appends the +value on the right side of the operator to the hash table. However, because the +only type that you can add to a hash table is another hash table, all other +assignments fail. + +For example, the following command assigns a hash table to the `$a` variable. +Then, it uses the `+=` operator to append another hash table to the existing +hash table, effectively adding a new key-value pair to the existing hash table. +This command succeeds, as shown in the output: + +```powershell +$a = @{a = 1; b = 2; c = 3} +$a += @{mode = "write"} +$a +``` + +```Output +Name Value +---- ----- +a 1 +b 2 +mode write +c 3 +``` + +The following command attempts to append an integer "1" to the hash table in +the `$a` variable. This command fails: + +```powershell +$a = @{a = 1; b = 2; c = 3} +$a += 1 +``` + +```Output +InvalidOperation: +Line | + 2 | $a += 1 + | ~~~~~~~ + | A hash table can only be added to another hash table. +``` + +### The assignment by subtraction operator + +The assignment by subtraction operator `-=` decrements the value of a variable +by the value that's specified on the right side of the operator. This operator +can't be used with string variables, and it can't be used to remove an element +from a collection. + +The `-=` operator combines two operations. First, it subtracts, and then it +assigns. Therefore, the following statements are equivalent: + +```powershell +$a -= 2 +$a = ($a - 2) +``` + +The following example shows how to use of the `-=` operator to decrease the +value of a variable: + +```powershell +$a = 8 +$a -= 2 +$a +``` + +```Output +6 +``` + +You can also use the `-=` assignment operator to decrease the value of a member +of a numeric array. To do this, specify the index of the array element that you +want to change. In the following example, the value of the third element of an +array (element 2) is decreased by 1: + +```powershell +$a = 1,2,3 +$a[2] -= 1 +$a +``` + +```Output +1 +2 +2 +``` + +You can't use the `-=` operator to delete the values of a variable. To delete +all the values that are assigned to a variable, use the [Clear-Item][06] or +[Clear-Variable][07] cmdlets to assign a value of `$null` or `""` to the +variable. + +```powershell +$a = $null +``` + +To delete a particular value from an array, use array notation to assign a +value of `$null` to the particular item. For example, the following statement +deletes the second value (index position 1) from an array: + +```powershell +$a = 1,2,3 +$a +``` + +```Output +1 +2 +3 +``` + +```powershell +$a[1] = $null +$a +``` + +```Output +1 +3 +``` + +To delete a variable, use the [Remove-Variable][08] cmdlet. This method is +useful when the variable is explicitly cast to a particular data type, and you +want an untyped variable. The following command deletes the `$a` variable: + +```powershell +Remove-Variable -Name a +``` + +### The assignment by multiplication operator + +The assignment by multiplication operator `*=` multiplies a numeric value or +appends the specified number of copies of the string value of a variable. + +When a variable contains a single numeric value, that value is multiplied by +the value on the right side of the operator. For example, the following example +shows how to use the `*=` operator to multiply the value of a variable: + +```powershell +$a = 3 +$a *= 4 +$a +``` + +```Output +12 +``` + +In this case, the `*=` operator combines two operations. First, it multiplies, +and then it assigns. Therefore, the following statements are equivalent: + +```powershell +$a *= 2 +$a = ($a * 2) +``` + +When a variable contains a string value, PowerShell appends the specified +number of strings to the value, as follows: + +```powershell +$a = "file" +$a *= 4 +$a +``` + +```Output +filefilefilefile +``` + +To multiply an element of an array, use an index to identify the element that +you want to multiply. For example, the following command multiplies the first +element in the array (index position 0) by 2: + +```powershell +$a[0] *= 2 +``` + +### The assignment by division operator + +The assignment by division operator `/=` divides a numeric value by the value +that's specified on the right side of the operator. The operator can't be used +with string variables. + +The `/=` operator combines two operations. First, it divides, and then it +assigns. Therefore, the following two statements are equivalent: + +```powershell +$a /= 2 +$a = ($a / 2) +``` + +For example, the following command uses the `/=` operator to divide the value +of a variable: + +```powershell +$a = 8 +$a /=2 +$a +``` + +```Output +4 +``` + +To divide an element of an array, use an index to identify the element that you +want to change. For example, the following command divides the second element +in the array (index position 1) by 2: + +```powershell +$a[1] /= 2 +``` + +### The assignment by modulus operator + +The assignment by modulus operator `%=` divides the value of a variable by the +value on the right side of the operator. Then, the `%=` operator assigns the +remainder (known as the modulus) to the variable. You can use this operator +only when a variable contains a single numeric value. You can't use this +operator when a variable contains a string variable or an array. + +The `%=` operator combines two operations. First, it divides and determines the +remainder, and then it assigns the remainder to the variable. Therefore, the +following statements are equivalent: + +```powershell +$a %= 2 +$a = ($a % 2) +``` + +The following example shows how to use the `%=` operator to save the modulus of +a quotient: + +```powershell +$a = 7 +$a %= 4 +$a +``` + +```Output +3 +``` + +### The increment and decrement operators + +The increment operator `++` increases the value of a variable by 1. When you +use the increment operator in a simple statement, no value is returned. To view +the result, display the value of the variable, as follows: + +```powershell +$a = 7 +++$a +$a +``` + +```Output +8 +``` + +To force a value to be returned, enclose the variable and the operator in +parentheses, as follows: + +```powershell +$a = 7 +(++$a) +``` + +```Output +8 +``` + +The increment operator can be placed before (prefix) or after (postfix) a +variable. The prefix version of the operator increments a variable before its +value is used in the statement, as follows: + +```powershell +$a = 7 +$c = ++$a +$a +``` + +```Output +8 +``` + +```powershell +$c +``` + +```Output +8 +``` + +The postfix version of the operator increments a variable after its value is +used in the statement. In the following example, the `$c` and `$a` variables +have different values because the value is assigned to `$c` before `$a` +changes: + +```powershell +$a = 7 +$c = $a++ +$a +``` + +```Output +8 +``` + +```powershell +$c +``` + +```Output +7 +``` + +The decrement operator `--` decreases the value of a variable by 1. As with the +increment operator, no value is returned when you use the operator in a simple +statement. Use parentheses to return a value, as follows: + +```powershell +$a = 7 +--$a +$a +``` + +```Output +6 +``` + +```powershell +(--$a) +``` + +```Output +5 +``` + +The prefix version of the operator decrements a variable before its value is +used in the statement, as follows: + +```powershell +$a = 7 +$c = --$a +$a +``` + +```Output +6 +``` + +```powershell +$c +``` + +```Output +6 +``` + +The postfix version of the operator decrements a variable after its value is +used in the statement. In the following example, the `$d` and `$a` variables +have different values because the value is assigned to `$d` before `$a` +changes: + +```powershell +$a = 7 +$d = $a-- +$a +``` + +```Output +6 +``` + +```powershell +$d +``` + +```Output +7 +``` + +### Null-coalescing assignment operator + +The null-coalescing assignment operator `??=` assigns the value of its +right-hand operand to its left-hand operand only if the left-hand operand +evaluates to null. The `??=` operator doesn't evaluate its right-hand operand +if the left-hand operand evaluates to non-null. + +```powershell +$x = $null +$x ??= 100 +$x +``` + +```Output +100 +``` + +For more information, see +[Null-coalescing operator][04]. + +## Microsoft .NET types + +By default, when a variable has only one value, the value that's assigned to +the variable determines the data type of the variable. For example, the +following command creates a variable that has the **System.Int32** type: + +```powershell +$a = 6 +``` + +To find the .NET type of a variable, use the **GetType** method and its +**FullName** property. Be sure to include the parentheses after the **GetType** +method name, even though the method call has no arguments: + +```powershell +$a = 6 +$a.GetType().FullName +``` + +```Output +System.Int32 +``` + +To create a variable that contains a string, assign a string value to the +variable. To indicate that the value is a string, enclose it in quotation +marks, as follows: + +```powershell +$a = "6" +$a.GetType().FullName +``` + +```Output +System.String +``` + +If the first value that's assigned to the variable is a string, PowerShell +treats all operations as string operations and casts new values to strings. +This occurs in the following example: + +```powershell +$a = "file" +$a += 3 +$a +``` + +```Output +file3 +``` + +If the first value is an integer, PowerShell treats all operations as integer +operations and casts new values to integers. This occurs in the following +example: + +```powershell +$a = 6 +$a += "3" +$a +``` + +```Output +9 +``` + +You can cast a new [scalar][01] variable as any .NET type by placing the type +name in brackets that precede either the variable name or the first assignment +value. When you cast a variable, you are defining the type of data that can be +stored in the variable. + +For example, the following command casts the variable as a string type: + +```powershell +[string]$a = 27 +$a += 3 +$a +``` + +```Output +273 +``` + +The following example casts the first value, instead of casting the variable: + +```powershell +$a = [string]27 +``` + +You can't recast the data type of an existing variable if its value can't be +converted to the new data type. + +```powershell +$a = "string" +[int]$a +``` + +```Output +InvalidArgument: Cannot convert value "string" to type "System.Int32". Error: +"The input string 'string' was not in a correct format." +``` + +To change the data type, you must replace its value, as follows: + +```powershell +[int]$a = 3 +``` + +In addition, when you precede a variable name with a data type, the type of +that variable is locked unless you explicitly override the type by specifying +another data type. If you try to assign a value that's incompatible with the +existing type, and you don't explicitly override the type, PowerShell displays +an error, as shown in the following example: + +```powershell +$a = 3 +$a = "string" +[int]$a = 3 +$a = "string" +``` + +```Output +MetadataError: +Line | + 2 | $a = "string" + | ~~~~~~~~~~~~~ + | Cannot convert value "string" to type "System.Int32". Error: "The input +string 'string' was not in a correct format." +``` + +```powershell +[string]$a = "string" +``` + +In PowerShell, the data types of variables that contain multiple items in an +array are handled differently from the data types of variables that contain a +single item. Unless a data type is specifically assigned to an array variable, +the data type is always `System.Object []`. This data type is specific to +arrays. + +Sometimes, you can override the default type by specifying another type. For +example, the following command casts the variable as a `string []` array type: + +```powershell +[string []] $a = "one", "two", "three" +``` + +PowerShell variables can be any .NET data type. In addition, you can assign any +fully qualified .NET data type that's available in the current process. For +example, the following command specifies a `System.DateTime` data type: + +```powershell +[System.DateTime]$a = "5/31/2005" +``` + +The variable will be assigned a value that conforms to the `System.DateTime` +data type. The value of the `$a` variable would be the following: + +```Output +Tuesday, May 31, 2005 12:00:00 AM +``` + +## Assigning multiple variables + +In PowerShell, you can assign values to multiple variables using a single +command. The first element of the assignment value is assigned to the first +variable, the second element is assigned to the second variable, the third +element to the third variable. This is known as _multiple assignment_. + +For example, the following command assigns the value 1 to the `$a` variable, +the value 2 to the `$b` variable, and the value 3 to the `$c` variable: + +```powershell +$a, $b, $c = 1, 2, 3 +``` + +If the assignment value contains more elements than variables, all the +remaining values are assigned to the last variable. For example, the following +command contains three variables and five values: + +```powershell +$a, $b, $c = 1, 2, 3, 4, 5 +``` + +Therefore, PowerShell assigns the value 1 to the `$a` variable and the value 2 +to the `$b` variable. It assigns the values 3, 4, and 5 to the `$c` variable. +To assign the values in the `$c` variable to three other variables, use the +following format: + +```powershell +$d, $e, $f = $c +``` + +This command assigns the value 3 to the `$d` variable, the value 4 to the `$e` +variable, and the value 5 to the `$f` variable. + +If the assignment value contains fewer elements than variables, the remaining +variables are assigned the value `$null`. For example, the following command +contains three variables and two values: + +```powershell +$a, $b, $c = 1, 2 +``` + +Therefore, PowerShell assigns the value 1 to the `$a` variable and the value 2 +to the `$b` variable. The `$c` variable is `$null`. + +You can also assign a single value to multiple variables by chaining the +variables. For example, the following command assigns a value of "three" to all +four variables: + +```powershell +$a = $b = $c = $d = "three" +``` + +## Variable-related cmdlets + +In addition to using an assignment operation to set a variable value, you can +also use the [Set-Variable][09] cmdlet. For example, the following command uses +`Set-Variable` to assign an array of 1, 2, 3 to the `$a` variable. + +```powershell +Set-Variable -Name a -Value 1, 2, 3 +``` + +## See also + +- [about_Arrays][02] +- [about_Hash_Tables][03] +- [about_Variables][05] +- [Clear-Variable][07] +- [Remove-Variable][08] +- [Set-Variable][09] + + +[01]: /powershell/scripting/learn/glossary#scalar-value +[02]: about_Arrays.md +[03]: about_Hash_Tables.md +[04]: about_operators.md#null-coalescing-operator- +[05]: about_Variables.md +[06]: xref:Microsoft.PowerShell.Management.Clear-Item +[07]: xref:Microsoft.PowerShell.Utility.Clear-Variable +[08]: xref:Microsoft.PowerShell.Utility.Remove-Variable +[09]: xref:Microsoft.PowerShell.Utility.Set-Variable diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md new file mode 100644 index 000000000000..812e618379eb --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -0,0 +1,1158 @@ +--- +description: Describes variables that store state information for PowerShell. These variables are created and maintained by PowerShell. +Locale: en-US +ms.date: 01/07/2025 +no-loc: [Reset, Current, Background, Blink, Bold, Foreground, Formatting, Hidden, Italic, Reset, Reverse, Underline, PSEventArgs, PSEventSubscriber, PSEdition] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Automatic_Variables +--- + +# about_Automatic_Variables + +## Short description + +Describes variables that store state information for and are created and +maintained by PowerShell. + +Conceptually, most of these variables are considered to be read-only. Even +though they _can_ be written to, for backward compatibility they _should not_ +be written to. + +Here is a list of the automatic variables in PowerShell: + +- [`$$`][40] +- [`$?`][41] +- [`$^`][42] +- [`$_`][02] +- [`$args`][03] +- [`$ConsoleFileName`][04] +- [`$EnabledExperimentalFeatures`][05] +- [`$Error`][06] +- [`$Event`][07] +- [`$EventArgs`][08] +- [`$EventSubscriber`][09] +- [`$ExecutionContext`][10] +- [`$false`][11] +- [`$foreach`][12] +- [`$HOME`][13] +- [`$Host`][14] +- [`$input`][15] +- [`$IsCoreCLR`][16] +- [`$IsLinux`][17] +- [`$IsMacOS`][18] +- [`$IsWindows`][19] +- [`$LASTEXITCODE`][20] +- [`$Matches`][21] +- [`$MyInvocation`][22] +- [`$NestedPromptLevel`][23] +- [`$null`][24] +- [`$PID`][25] +- [`$PROFILE`][26] +- [`$PSBoundParameters`][27] +- [`$PSCmdlet`][28] +- [`$PSCommandPath`][29] +- [`$PSCulture`][30] +- [`$PSDebugContext`][31] +- [`$PSEdition`][32] +- [`$PSHOME`][33] +- [`$PSItem`][34] +- [`$PSScriptRoot`][35] +- [`$PSSenderInfo`][36] +- [`$PSUICulture`][37] +- [`$PSVersionTable`][38] +- [`$PWD`][39] +- [`$Sender`][43] +- [`$ShellId`][44] +- [`$StackTrace`][45] +- [`$switch`][46] +- [`$this`][47] +- [`$true`][48] + +## Long description + +### `$$` + +Contains the last token in the last line received by the session. + +### `$?` + +Contains the execution status of the last command. It contains **True** if the +last command succeeded and **False** if it failed. Parse errors don't result in +execution, so they don't affect the value of `$?`. + +For cmdlets and advanced functions that are run at multiple stages in a +pipeline, for example in both `process` and `end` blocks, calling +`this.WriteError()` or `$PSCmdlet.WriteError()` respectively at any point sets +`$?` to **False**, as does `this.ThrowTerminatingError()` and +`$PSCmdlet.ThrowTerminatingError()`. + +The `Write-Error` cmdlet always sets `$?` to **False** immediately after it's +executed, but won't set `$?` to **False** for a function calling it: + +```powershell +function Test-WriteError +{ + Write-Error "Bad" + "The `$? variable is: $?" +} + +Test-WriteError +"Now the `$? variable is: $?" +``` + +```Output +Test-WriteError: +Line | + 7 | Test-WriteError + | ~~~~~~~~~~~~~~~ + | Bad +The $? variable is: False +Now the $? variable is: True +``` + +For the latter purpose, `$PSCmdlet.WriteError()` should be used instead. + +For native commands (executables), `$?` is set to **True** when `$LASTEXITCODE` +is 0, and set to **False** when `$LASTEXITCODE` is any other value. + +> [!NOTE] +> Until PowerShell 7, wrapping a statement within parentheses `(...)`, +> subexpression syntax `$(...)`, or an array expression `@(...)` always reset +> `$?` to **True**. For example, `(Write-Error)` shows `$?` as **True**. This +> behavior changed in PowerShell 7, so that `$?` always reflects the actual +> success of the last command run in these expressions. + +### `$^` + +Contains the first token in the last line received by the session. + +### `$_` + +Same as `$PSItem`. Contains the current object in the pipeline object. You can +use this variable in commands that perform an action on every object in a +pipeline. + +For more information, see [about_PSItem][67]. + +### `$args` + +Contains an array of values for undeclared parameters that are passed to a +function, script, or script block. When you create a function, you can declare +the parameters with the `param` keyword or by adding a comma-separated list of +parameters in parentheses after the function name. + +In an event action, the `$args` variable contains objects that represent the +event arguments of the event that's being processed. This variable is populated +only within the `Action` block of an event registration command. The value of +this variable can also be found in the **SourceArgs** property of the +**PSEventArgs** object that `Get-Event` returns. + +### `$ConsoleFileName` + +Contains the path of the console file (`.psc1`) that was most recently used in +the session. This variable is populated when you start PowerShell with the +**PSConsoleFile** parameter or when you use the `Export-Console` cmdlet to +export snap-in names to a console file. + +When you use the `Export-Console` cmdlet without parameters, it automatically +updates the console file that was most recently used in the session. You can +use this automatic variable to determine the file to update. + +### `$EnabledExperimentalFeatures` + +Contains a list of names of the experimental features that are enabled. + +### `$Error` + +Contains an array of error objects that represent the most recent errors. The +most recent error is the first error object in the array `$Error[0]`. + +To prevent an error from being added to the `$Error` array, use the +**ErrorAction** common parameter with a value of **Ignore**. For more +information, see [about_CommonParameters][53]. + +### `$Event` + +Contains a **PSEventArgs** object that represents the event that's being +processed. This variable is populated only within the `Action` block of an +event registration command, such as `Register-ObjectEvent`. The value of this +variable is the same object that the `Get-Event` cmdlet returns. You can use +the properties of the `Event` variable, such as `$Event.TimeGenerated`, in an +`Action` script block. + +### `$EventArgs` + +Contains an object that represents the first event argument that derives from +**EventArgs** of the event that's being processed. This variable is populated +only within the `Action` block of an event registration command. The value of +this variable can also be found in the **SourceEventArgs** property of the +**PSEventArgs** object that `Get-Event` returns. + +### `$EventSubscriber` + +Contains a **PSEventSubscriber** object that represents the event subscriber of +the event that's being processed. This variable is populated only within the +`Action` block of an event registration command. The value of this variable is +the same object that the `Get-EventSubscriber` cmdlet returns. + +### `$ExecutionContext` + +Contains an **EngineIntrinsics** object that represents the execution context +of the PowerShell host. You can use this variable to find the execution objects +that are available to cmdlets. + +### `$false` + +Contains **False**. You can use this variable to represent **False** in +commands and scripts instead of using the string `"false"`. The string can be +interpreted as **True** if it's converted to a non-empty string or to a +non-zero integer. + +### `$foreach` + +Contains the enumerator (not the resulting values) of a [ForEach][56] loop. The +`$ForEach` variable exists only while the `ForEach` loop is running; it's +deleted after the loop is completed. + +Enumerators contain properties and methods you can use to retrieve loop values +and change the current loop iteration. For more information, see +[Using Enumerators][49]. + +### `$HOME` + +Contains the full path of the user's home directory. On Windows, this variable +uses the value of the `"$env:USERPROFILE"` Windows environment variable, +typically `C:\Users\`. On Unix, this variable uses the value of the +`HOME` environment variable. + +> [!IMPORTANT] +> Windows can redirect the location of the user's profile. This means that +> `$HOME` may not have the same value as `"$env:HOMEDRIVE$env:HOMEPATH"`. + +### `$Host` + +Contains an object that represents the current host application for PowerShell. +You can use this variable to represent the current host in commands or to +display or change the properties of the host, such as `$Host.version` or +`$Host.CurrentCulture`, or `$Host.UI.RawUI.BackGroundColor = "Red"`. + +> [!NOTE] +> The color settings in `$Host.PrivateData` have been replaced by the +> `$PSStyle` preference variable. For more information, see +> [about_ANSI_Terminals][50]. + +### `$input` + +Contains an enumerator that enumerates all input that's passed to a function. +The `$input` variable is available only to functions, script blocks (which +are unnamed functions), and script files (which are saved script blocks). + +- In a function without a `begin`, `process`, or `end` block, the `$input` + variable enumerates the collection of all input to the function. + +- In the `begin` block, the `$input` variable contains no data. + +- In the `process` block, the `$input` variable contains the current object in + the pipeline. + +- In the `end` block, the `$input` variable enumerates the collection of all + input to the function. + + > [!NOTE] + > You can't use the `$input` variable inside both the `process` block and the + > `end` block in the same function or script block. + +Since `$input` is an enumerator, accessing any of its properties causes +`$input` to no longer be available. You can store `$input` in another variable +to reuse the `$input` properties. + +Enumerators contain properties and methods you can use to retrieve loop values +and change the current loop iteration. For more information, see +[Using Enumerators][49]. + +The `$input` variable is also available to the command specified by the +`-Command` parameter of `pwsh` when invoked from the command line. The +following example is run from the Windows Command shell. + +```CMD +echo Hello | pwsh -Command """$input World!""" +``` + +### `$IsCoreCLR` + +Contains `$true` if the current session is running on the .NET Core Runtime +(CoreCLR). Otherwise contains `$false`. + +### `$IsLinux` + +Contains `$true` if the current session is running on a Linux operating system. +Otherwise contains `$false`. + +### `$IsMacOS` + +Contains `$true` if the current session is running on a macOS operating system. +Otherwise contains `$false`. + +### `$IsWindows` + +Contains `$true` if the current session is running on a Windows operating +system. Otherwise contains `$false`. + +### `$LASTEXITCODE` + +Contains the exit code of the last native program or PowerShell script that +ran. + +For PowerShell scripts, the value of `$LASTEXITCODE` depends on how the script +was called and whether the `exit` keyword was used: + +- When a script uses the `exit` keyword: + + `$LASTEXITCODE` is set to value the specified by the `exit` keyword. For more + information, see [about_Language_Keywords][64]. + +- When a script is called directly, like `./Test.ps1`, or with the + [call operator][65] (`&`) like `& ./Test.ps1`: + + The value of `$LASTEXITCODE` isn't changed unless: + + - The script calls another script that uses the `exit` keyword + - The script calls a native command + - The script uses the `exit` keyword + +- When a script is called with `pwsh` using the **File** parameter, + `$LASTEXITCODE` is set to: + + - `1` if the script terminated due to an exception + - The value specified by the `exit` keyword, if used in the script + - `0` if the script completed successfully + +- When a script is called with `pwsh` using the **Command** parameter, + `$LASTEXITCODE` is set to: + + - `1` if the script terminated due to an exception or if the result of the + last command set `$?` to `$false` + - `0` if the script completed successfully and the result of the last command + set `$?` to `$true` + +For more information on the **File** and **Command** parameters, see +[about_Pwsh][68]. + +### `$Matches` + +The `$Matches` variable works with the `-match` and `-notmatch` operators. When +you submit [scalar][01] input to the `-match` or `-notmatch` operator, and +either one detects a match, they return a Boolean value and populate the +`$Matches` automatic variable with a hash table of any string values that were +matched. The `$Matches` hash table can also be populated with captures when you +use regular expressions with the `-match` operator. + +For more information about the `-match` operator, see +[about_Comparison_Operators][54]. For more information on regular expressions, +see [about_Regular_Expressions][69]. + +The `$Matches` variable also works in a `switch` statement with the `-Regex` +parameter. It's populated the same way as the `-match` and `-notmatch` +operators. For more information about the `switch` statement, see +[about_Switch][71]. + +> [!NOTE] +> When `$Matches` is populated in a session, it retains the matched value until +> it's overwritten by another match. If `-match` is used again and no match is +> found, it doesn't reset `$Matches` to `$null`. The previously matched value +> is kept in `$Matches` until another match is found. + +### `$MyInvocation` + +Contains information about the current command, such as the name, parameters, +parameter values, and information about how the command was started, called, or +invoked, such as the name of the script that called the current command. + +`$MyInvocation` is populated only for scripts, function, and script blocks. You +can use the information in the **System.Management.Automation.InvocationInfo** +object that `$MyInvocation` returns in the current script, such as the name of +a function (`$MyInvocation.MyCommand.Name`) to identify the current command. +This is useful for finding the name of the current script. + +Beginning in PowerShell 3.0, `MyInvocation` has the following new properties. + +- **PSScriptRoot** - Contains the full path to the script that invoked the + current command. The value of this property is populated only when the caller + is a script. +- **PSCommandPath** - Contains the full path and filename of the script that + invoked the current command. The value of this property is populated only + when the caller is a script. + +Unlike the `$PSScriptRoot` and `$PSCommandPath` automatic variables, the +**PSScriptRoot** and **PSCommandPath** properties of the `$MyInvocation` +automatic variable contain information about the invoker or calling script, not +the current script. + +### `$NestedPromptLevel` + +Contains the current prompt level. A value of 0 indicates the original prompt +level. The value is incremented when you enter a nested level and decremented +when you exit it. + +For example, PowerShell presents a nested command prompt when you use the +`$Host.EnterNestedPrompt` method. PowerShell also presents a nested command +prompt when you reach a breakpoint in the PowerShell debugger. + +When you enter a nested prompt, PowerShell pauses the current command, saves +the execution context, and increments the value of the `$NestedPromptLevel` +variable. To create additional nested command prompts (up to 128 levels) or to +return to the original command prompt, complete the command, or type `exit`. + +The `$NestedPromptLevel` variable helps you track the prompt level. You can +create an alternative PowerShell command prompt that includes this value so +that it's always visible. + +### `$null` + +`$null` is an automatic variable that contains a **null** or empty value. You +can use this variable to represent an absent or undefined value in commands and +scripts. + +PowerShell treats `$null` as an object with a value, or a placeholder, so you +can use `$null` to represent an empty value in a collection of values. + +For example, when `$null` is included in a collection, it's counted as one of +the objects. + +```powershell +$a = "one", $null, "three" +$a.count +``` + +```Output +3 +``` + +If you pipe the `$null` variable to the `ForEach-Object` cmdlet, it generates a +value for `$null`, just as it does for the other objects + +```powershell +"one", $null, "three" | ForEach-Object { "Hello " + $_} +``` + +```Output +Hello one +Hello +Hello three +``` + +As a result, you can't use `$null` to mean **no parameter value**. A parameter +value of `$null` overrides the default parameter value. + +However, because PowerShell treats the `$null` variable as a placeholder, you +can use it in scripts like the following one, which wouldn't work if `$null` +were ignored. + +```powershell +$calendar = @($null, $null, "Meeting", $null, $null, "Team Lunch", $null) +$days = "Sunday","Monday","Tuesday","Wednesday","Thursday", + "Friday","Saturday" +$currentDay = 0 +foreach($day in $calendar) +{ + if($day -ne $null) + { + "Appointment on $($days[$currentDay]): $day" + } + + $currentDay++ +} +``` + +```Output +Appointment on Tuesday: Meeting +Appointment on Friday: Team lunch +``` + +### `$PID` + +Contains the process identifier (PID) of the process that's hosting the +current PowerShell session. + +### `$PROFILE` + +Contains the full path of the PowerShell profile for the current user and the +current host application. You can use this variable to represent the profile in +commands. For example, you can use it in a command to determine whether a +profile has been created: + +```powershell +Test-Path $PROFILE +``` + +Or, you can use it in a command to create a profile: + +```powershell +New-Item -ItemType file -Path $PROFILE -Force +``` + +You can use it in a command to open the profile in **notepad.exe**: + +```powershell +notepad.exe $PROFILE +``` + +### `$PSBoundParameters` + +Contains a dictionary of the parameters that are passed to a script or function +and their current values. This variable has a value only in a scope where +parameters are declared, such as a script or function. You can use it to +display or change the current values of parameters or to pass parameter values +to another script or function. + +In this example, the **Test2** function passes the `$PSBoundParameters` to the +**Test1** function. The `$PSBoundParameters` are displayed in the format of +**Key** and **Value**. + +```powershell +function Test1 { + param($a, $b) + + # Display the parameters in dictionary format. + $PSBoundParameters +} + +function Test2 { + param($a, $b) + + # Run the Test1 function with $a and $b. + Test1 @PSBoundParameters +} +``` + +```powershell +Test2 -a Power -b Shell +``` + +```Output +Key Value +--- ----- +a Power +b Shell +``` + +### `$PSCmdlet` + +Contains an object that represents the cmdlet or advanced function that's being +run. + +You can use the properties and methods of the object in your cmdlet or function +code to respond to the conditions of use. For example, the **ParameterSetName** +property contains the name of the parameter set that's being used, and the +**ShouldProcess** method adds the **WhatIf** and **Confirm** parameters to the +cmdlet dynamically. + +For more information about the `$PSCmdlet` automatic variable, see +[about_Functions_CmdletBindingAttribute][60] and +[about_Functions_Advanced][59]. + +### `$PSCommandPath` + +Contains the full path and filename of the script that's being run. This +variable is valid in all scripts. + +### `$PSCulture` + +Beginning in PowerShell 7, `$PSCulture` reflects the culture of the current +PowerShell runspace (session). If the culture is changed in a PowerShell +runspace, the `$PSCulture` value for that runspace is updated. + +The culture determines the display format of items such as numbers, currency, +and dates, and is stored in a **System.Globalization.CultureInfo** object. Use +`Get-Culture` to display the computer's culture. `$PSCulture` contains the +**Name** property's value. + +### `$PSDebugContext` + +While debugging, this variable contains information about the debugging +environment. Otherwise, it contains a **null** value. As a result, you can use +it to determine whether the debugger has control. When populated, it contains a +**PsDebugContext** object that has **Breakpoints** and **InvocationInfo** +properties. The **InvocationInfo** property has several useful properties, +including the **Location** property. The **Location** property indicates the +path of the script that's being debugged. + +### `$PSEdition` + +Contains the same value in `$PSVersionTable.PSEdition`. This variable is +available for use in module manifest files, whereas `$PSVersionTable` isn't. + +### `$PSHOME` + +Contains the full path of the installation directory for PowerShell, typically, +`C:\Program Files\PowerShell\7` in Windows systems. You can use this variable +in the paths of PowerShell files. For example, the following command searches +the conceptual Help topics for the word **Help**: + +```powershell +Select-String -Pattern Help -Path $PSHOME\en-US\*.txt +``` + +### `$PSItem` + +Same as `$_`. Contains the current object in the pipeline object. You can use +this variable in commands that perform an action on every object in a pipeline. + +For more information, see [about_PSItem][67]. + +### `$PSScriptRoot` + +Contains the full path of the executing script's parent directory. + +In PowerShell 2.0, this variable is valid only in script modules (`.psm1`). +Beginning in PowerShell 3.0, it's valid in all scripts. + +### `$PSSenderInfo` + +Contains information about the user who started the PSSession, including the +user identity and the time zone of the originating computer. This variable is +available only in PSSessions. + +The `$PSSenderInfo` variable includes a user-configurable property, +**ApplicationArguments**, that by default, contains only the `$PSVersionTable` +from the originating session. To add data to the **ApplicationArguments** +property, use the **ApplicationArguments** parameter of the +`New-PSSessionOption` cmdlet. + +### `$PSUICulture` + +Contains the name of the user interface (UI) culture that's configured in the +operating system. The UI culture determines which text strings are used for +user interface elements, such as menus and messages. This is the value of the +**System.Globalization.CultureInfo.CurrentUICulture.Name** property of the +system. To get the **System.Globalization.CultureInfo** object for the system, +use the `Get-UICulture` cmdlet. + +### `$PSVersionTable` + +Contains a read-only hash table that displays details about the version of +PowerShell that's running in the current session. The table includes the +following items: + +- **PSVersion** - The PowerShell version number +- **PSEdition** This property has the value of 'Desktop' for PowerShell 4 and + below as well as PowerShell 5.1 on full-featured Windows editions. This + property has the value of `Core` for PowerShell 6 and higher as well as + Windows PowerShell 5.1 on reduced-footprint editions like Windows Nano Server + or Windows IoT. +- **GitCommitId** - The commit Id of the source files, in GitHub, +- **OS** - Description of the operating system that PowerShell is running on. +- **Platform** - Platform that the operating system is running on. The value on + Linux and macOS is **Unix**. See `$IsMacOs` and `$IsLinux`. +- **PSCompatibleVersions** - Versions of PowerShell that are compatible with + the current version +- **PSRemotingProtocolVersion** - The version of the PowerShell remote + management protocol. +- **SerializationVersion** - The version of the serialization method +- **WSManStackVersion** - The version number of the WS-Management stack + +### `$PWD` + +Contains a path object that represents the full path of the current directory +location for the current PowerShell runspace. + +> [!NOTE] +> PowerShell supports multiple runspaces per process. Each runspace has its own +> _current directory_. This isn't the same as the current directory of the +> process: `[System.Environment]::CurrentDirectory`. + +### `$Sender` + +Contains the object that generated this event. This variable is populated only +within the Action block of an event registration command. The value of this +variable can also be found in the Sender property of the **PSEventArgs** object +that `Get-Event` returns. + +### `$ShellId` + +Contains the identifier of the current shell. + +### `$StackTrace` + +Contains a stack trace for the most recent error. + +### `$switch` + +Contains the enumerator not the resulting values of a `Switch` statement. The +`$switch` variable exists only while the `Switch` statement is running; it's +deleted when the `switch` statement completes execution. For more information, +see [about_Switch][71]. + +Enumerators contain properties and methods you can use to retrieve loop values +and change the current loop iteration. For more information, see +[Using Enumerators][49]. + +### `$this` + +The `$this` variable is used in script blocks that extend classes to refer to +the instance of the class itself. + +PowerShell's Extensible Type System (ETS) allows you to add properties to +classes using script blocks. In a script block that defines a script property +or script method, the `$this` variable refers to an instance of object of the +class that's being extended. For example, PowerShell uses ETS to add the +**BaseName** property to the **FileInfo** class. + +```powershell +PS> Get-ChildItem .\README.md | Get-Member BaseName | Format-List + +TypeName : System.IO.FileInfo +Name : BaseName +MemberType : ScriptProperty +Definition : System.Object BaseName {get=if ($this.Extension.Length -gt 0) + {$this.Name.Remove($this.Name.Length - $this.Extension.Length + )}else{$this.Name};} +``` + +For more information, see [about_Types.ps1xml][72]. + +In a PowerShell class, the `$this` variable refers to the instance object of +the class itself, allowing access to properties and methods defined in the +class. For more information, see [about_Classes][52]. + +The `$this` variable is also used by .NET event classes that take script blocks +as delegates for the event handler. In this scenario, `$this` represents the +object originating the event, known as the event sender. + +### `$true` + +Contains **True**. You can use this variable to represent **True** in commands +and scripts. + +## Using Enumerators + +The `$input`, `$foreach`, and `$switch` variables are all enumerators used to +iterate through the values processed by their containing code block. + +An enumerator contains properties and methods you can use to advance or reset +iteration, or retrieve iteration values. Directly manipulating enumerators +isn't considered best practice. + +- Within loops, flow control keywords [break][51] and [continue][55] should be + preferred. +- Within functions that accept pipeline input, it's best practice to use + parameters with the **ValueFromPipeline** or + **ValueFromPipelineByPropertyName** attributes. + + For more information, see [about_Functions_Advanced_Parameters][58]. + +### MoveNext + +The [MoveNext][76] method +advances the enumerator to the next element of the collection. **MoveNext** +returns `True` if the enumerator was successfully advanced, `False` if the +enumerator has passed the end of the collection. + +> [!NOTE] +> The **Boolean** value returned by **MoveNext** is sent to the output stream. +> You can suppress the output by typecasting it to `[void]` or piping it to +> [Out-Null][74]. +> +> ```powershell +> $input.MoveNext() | Out-Null +> ``` +> +> ```powershell +> [void]$input.MoveNext() +> ``` + +### Reset + +The [Reset][77] method sets the enumerator to its initial position, which is +**before** the first element in the collection. + +### Current + +The [Current][75] property gets the element in the collection, or pipeline, at +the current position of the enumerator. + +The **Current** property continues to return the same property until +**MoveNext** is called. + +## Examples + +### Example 1: Using the $input variable + +In the following example, accessing the `$input` variable clears the variable +until the next time the process block executes. Using the **Reset** method +resets the `$input` variable to the current pipeline value. + +```powershell +function Test +{ + begin + { + $i = 0 + } + + process + { + "Iteration: $i" + $i++ + "`tInput: $input" + "`tAccess Again: $input" + $input.Reset() + "`tAfter Reset: $input" + } +} + +"one","two" | Test +``` + +```Output +Iteration: 0 + Input: one + Access Again: + After Reset: one +Iteration: 1 + Input: two + Access Again: + After Reset: two +``` + +The process block automatically advances the `$input` variable even if you +don't access it. + +```powershell +$skip = $true +function Skip +{ + begin + { + $i = 0 + } + + process + { + "Iteration: $i" + $i++ + if ($skip) + { + "`tSkipping" + $skip = $false + } + else + { + "`tInput: $input" + } + } +} + +"one","two" | Skip +``` + +```Output +Iteration: 0 + Skipping +Iteration: 1 + Input: two +``` + +### Example 2: Using $input outside the process block + +Outside of the process block the `$input` variable represents all the values +piped into the function. + +- Accessing the `$input` variable clears all values. +- The **Reset** method resets the entire collection. +- The **Current** property is never populated. +- The **MoveNext** method returns false because the collection can't be + advanced. + - Calling **MoveNext** clears out the `$input` variable. + +```powershell +Function All +{ + "All Values: $input" + "Access Again: $input" + $input.Reset() + "After Reset: $input" + $input.MoveNext() | Out-Null + "After MoveNext: $input" +} + +"one","two","three" | All +``` + +```Output +All Values: one two three +Access Again: +After Reset: one two three +After MoveNext: +``` + +### Example 3: Using the $input.Current property + +With the **Current** property, the current pipeline value can be accessed +multiple times without using the **Reset** method. The process block doesn't +automatically call the **MoveNext** method. + +The **Current** property is never populated unless you explicitly call +**MoveNext**. The **Current** property can be accessed multiple times inside +the process block without clearing its value. + +```powershell +function Current +{ + begin + { + $i = 0 + } + + process + { + "Iteration: $i" + $i++ + "`tBefore MoveNext: $($input.Current)" + $input.MoveNext() | Out-Null + "`tAfter MoveNext: $($input.Current)" + "`tAccess Again: $($input.Current)" + } +} + +"one","two" | Current +``` + +```Output +Iteration: 0 + Before MoveNext: + After MoveNext: one + Access Again: one +Iteration: 1 + Before MoveNext: + After MoveNext: two + Access Again: two +``` + +### Example 4: Using the $foreach variable + +Unlike the `$input` variable, the `$foreach` variable always represents all +items in the collection when accessed directly. Use the **Current** property to +access the current collection element, and the **Reset** and **MoveNext** +methods to change its value. + +> [!NOTE] +> Each iteration of the `foreach` loop automatically calls the **MoveNext** +> method. + +The following loop only executes twice. In the second iteration, the collection +is moved to the third element before the iteration is complete. After the +second iteration, there are now no more values to iterate, and the loop +terminates. + +The **MoveNext** property doesn't affect the variable chosen to iterate through +the collection (`$Num`). + +```powershell +$i = 0 +foreach ($num in ("one","two","three")) +{ + "Iteration: $i" + $i++ + "`tNum: $num" + "`tCurrent: $($foreach.Current)" + + if ($foreach.Current -eq "two") + { + "Before MoveNext (Current): $($foreach.Current)" + $foreach.MoveNext() | Out-Null + "After MoveNext (Current): $($foreach.Current)" + "Num hasn't changed: $num" + } +} +``` + +```Output +Iteration: 0 + Num: one + Current: one +Iteration: 1 + Num: two + Current: two +Before MoveNext (Current): two +After MoveNext (Current): three +Num hasn't changed: two +``` + +Using the **Reset** method resets the current element in the collection. The +following example loops through the first two elements _twice_ because the +**Reset** method is called. After the first two loops, the `if` statement fails +and the loop iterates through all three elements normally. + +> [!IMPORTANT] +> This could result in an infinite loop. + +```powershell +$stopLoop = 0 +foreach ($num in ("one","two", "three")) +{ + ("`t" * $stopLoop) + "Current: $($foreach.Current)" + + if ($num -eq "two" -and $stopLoop -lt 2) + { + $foreach.Reset() + ("`t" * $stopLoop) + "Reset Loop: $stopLoop" + $stopLoop++ + } +} +``` + +```Output +Current: one +Current: two +Reset Loop: 0 + Current: one + Current: two + Reset Loop: 1 + Current: one + Current: two + Current: three +``` + +### Example 5: Using the $switch variable + +The `$switch` variable has the exact same rules as the `$foreach` variable. The +following example demonstrates all the enumerator concepts. + +> [!NOTE] +> Note how the **NotEvaluated** case is never executed, even though there's +> no `break` statement after the **MoveNext** method. + +```powershell +$values = "Start", "MoveNext", "NotEvaluated", "Reset", "End" +$stopInfinite = $false +switch ($values) +{ + "MoveNext" { + "`tMoveNext" + $switch.MoveNext() | Out-Null + "`tAfter MoveNext: $($switch.Current)" + } + # This case is never evaluated. + "NotEvaluated" { + "`tAfterMoveNext: $($switch.Current)" + } + + "Reset" { + if (!$stopInfinite) + { + "`tReset" + $switch.Reset() + $stopInfinite = $true + } + } + + default { + "Default (Current): $($switch.Current)" + } +} +``` + +```Output +Default (Current): Start + MoveNext + After MoveNext: NotEvaluated + Reset +Default (Current): Start + MoveNext + After MoveNext: NotEvaluated +Default (Current): End +``` + +## See also + +- [about_Functions][62] +- [about_Functions_Advanced][59] +- [about_Functions_Advanced_Methods][57] +- [about_Functions_Advanced_Parameters][58] +- [about_Functions_OutputTypeAttribute][61] +- [about_Functions_CmdletBindingAttribute][60] +- [about_Hash_Tables][63] +- [about_Preference_Variables][66] +- [about_Splatting][70] +- [about_Variables][73] + + +[01]: /powershell/scripting/learn/glossary#scalar-value +[02]: #_ +[03]: #args +[04]: #consolefilename +[05]: #enabledexperimentalfeatures +[06]: #error +[07]: #event +[08]: #eventargs +[09]: #eventsubscriber +[10]: #executioncontext +[11]: #false +[12]: #foreach +[13]: #home +[14]: #host +[15]: #input +[16]: #iscoreclr +[17]: #islinux +[18]: #ismacos +[19]: #iswindows +[20]: #lastexitcode +[21]: #matches +[22]: #myinvocation +[23]: #nestedpromptlevel +[24]: #null +[25]: #pid +[26]: #profile +[27]: #psboundparameters +[28]: #pscmdlet +[29]: #pscommandpath +[30]: #psculture +[31]: #psdebugcontext +[32]: #psedition +[33]: #pshome +[34]: #psitem +[35]: #psscriptroot +[36]: #pssenderinfo +[37]: #psuiculture +[38]: #psversiontable +[39]: #pwd +[40]: #section +[41]: #section-1 +[42]: #section-2 +[43]: #sender +[44]: #shellid +[45]: #stacktrace +[46]: #switch +[47]: #this +[48]: #true +[49]: #using-enumerators +[50]: about_ANSI_Terminals.md +[51]: about_Break.md +[52]: about_Classes.md +[53]: about_CommonParameters.md +[54]: about_comparison_operators.md +[55]: about_Continue.md +[56]: about_ForEach.md +[57]: about_Functions_Advanced_Methods.md +[58]: about_Functions_Advanced_Parameters.md +[59]: about_Functions_Advanced.md +[60]: about_Functions_CmdletBindingAttribute.md +[61]: about_Functions_OutputTypeAttribute.md +[62]: about_Functions.md +[63]: about_Hash_Tables.md +[64]: about_language_keywords.md#exit +[65]: about_operators.md#call-operator- +[66]: about_Preference_Variables.md +[67]: about_PSItem.md +[68]: about_Pwsh.md +[69]: about_Regular_Expressions.md +[70]: about_Splatting.md +[71]: about_Switch.md +[72]: about_Types.ps1xml.md +[73]: about_Variables.md +[74]: xref:Microsoft.PowerShell.Core.Out-Null +[75]: xref:System.Collections.IEnumerator.Current +[76]: xref:System.Collections.IEnumerator.MoveNext +[77]: xref:System.Collections.IEnumerator.Reset diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Booleans.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Booleans.md new file mode 100644 index 000000000000..b84379334fd9 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Booleans.md @@ -0,0 +1,116 @@ +--- +description: Describes how boolean expressions are evaluated. +Locale: en-US +ms.date: 01/19/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_booleans?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Booleans +--- +# about_Booleans + +## Short description + +Describes how boolean expressions are evaluated. + +## Long description + +PowerShell can implicitly treat any type as a **Boolean**. It is important to +understand the rules that PowerShell uses to convert other types to **Boolean** +values. + +## Converting from scalar types + +A [scalar][02] type is an atomic quantity that can hold only one value at a +time. The following types evaluate to `$false`: + +- Empty strings like `''` or `""` +- Null values like `$null` +- Any numeric type with the value of `0` + +Examples: + +```powershell +PS> $false -eq '' +True +PS> if ("") { $true } else { $false } +False +PS> if ($null) { $true } else { $false } +False +PS> if ([int]0) { $true } else { $false } +False +PS> if ([double]0.0) { $true } else { $false } +False +``` + +The following types evaluate to `$true`: + +- Non-empty strings +- Instances of any other non-collection type + +Examples: + +```powershell +# a non-collection type +PS> [bool]@{value = 0} +True +# non-empty strings +PS> if ('hello') { $true } else { $false } +True +PS> [bool]'False' +True +``` + +Note that this differs from _explicit string parsing_: + +```powershell +PS> [bool]::Parse('false') +False +PS> [bool]::Parse('True') +True +PS> [bool]::Parse('Not True') +MethodInvocationException: Exception calling "Parse" with "1" argument(s): +"String 'Not True' was not recognized as a valid Boolean." +``` + +## Converting from collection types + +Arrays are the most common collection type in PowerShell. These rules apply to +any collection-like types that implement the [IList][01] interface. + +- Empty collections are always `$false` +- The special null value indicating the absence of output from a command, + `[System.Management.Automation.Internal.AutomationNull]::Value` is always + `$false`. +- Single-element collections evaluate to the **Boolean** value of their one and + only element. +- Collections with more than 1 element are always `$true`. + +Examples: + +```powershell +# Empty collections +PS> [bool]@() +False +PS> [bool](Get-ChildItem | Where-Object Name -eq 'Non-existent-File.txt') +False +# Single-element collections +PS> $a = @(0) +PS> [bool]$a +False +PS> $b = @(1) +PS> [bool]$b +True +# Multi-element collections +PS> $c = @(0,0) +PS> [bool]$c +True +``` + +## See also + +- [about_Arrays][03] + + +[01]: /dotnet/api/system.collections.ilist +[02]: /powershell/scripting/learn/glossary#scalar-value +[03]: about_Arrays.md#where diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Break.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Break.md new file mode 100644 index 000000000000..aaf71bb6d45d --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Break.md @@ -0,0 +1,234 @@ +--- +description: Describes a statement you can use to immediately exit `foreach`, `for`, `while`, `do`, `switch`, or `trap` statements. +Locale: en-US +ms.date: 12/26/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_break?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Break +--- +# about_Break + +## Short description + +Describes the `break` statement, which provides a way to exit the current +control block. + +## Long description + +The `break` statement provides a way to exit the current control block. +Execution continues at the next statement after the control block. The +statement supports labels. A label is a name you assign to a statement in a +script. + +## Using `break` in loops + +When a `break` statement appears in a loop, such as a `foreach`, `for`, `do`, +or `while` loop, PowerShell immediately exits the loop. + +A `break` statement can include a label that lets you exit embedded loops. A +label can specify any loop keyword, such as `foreach`, `for`, or `while`, in a +script. + +The following example shows how to use a `break` statement to exit a `for` +statement: + +```powershell +for($i=1; $i -le 10; $i++) { + Write-Host $i + break +} +``` + +In this example, the `break` statement exits the `for` loop when the `$i` +variable equals 1. Even though the `for` statement evaluates to **True** until +`$i` is greater than 10, PowerShell reaches the break statement the first time +the `for` loop is run. + +It is more common to use the `break` statement in a loop where an inner +condition must be met. Consider the following `foreach` statement example: + +```powershell +$i=0 +$varB = 10,20,30,40 +foreach ($val in $varB) { + if ($val -eq 30) { + break + } + $i++ +} +Write-Host "30 was found in array index $i" +``` + +In this example, the `foreach` statement iterates the `$varB` array. The `if` +statement evaluates to False the first two times the loop is run and the +variable `$i` is incremented by 1. The third time the loop is run, `$i` equals +2, and the `$val` variable equals 30. At this point, the `break` statement +runs, and the `foreach` loop exits. + +### Using a labeled `break` in a loop + +A `break` statement can include a label. If you use the `break` keyword with a +label, PowerShell exits the labeled loop instead of exiting the current loop. +The label is a colon followed by a name that you assign. The label must be the +first token in a statement, and it must be followed by the looping keyword, +such as `while`. + +`break` moves execution out of the labeled loop. In embedded loops, this has a +different result than the `break` keyword has when it is used by itself. This +example has a `while` statement with a `for` statement: + +```powershell +:myLabel while () { + for ($item in $items) { + if () { + break myLabel + } + $item = $x # A statement inside the For-loop + } +} +$a = $c # A statement after the labeled While-loop +``` + +If condition 2 evaluates to **True**, the execution of the script skips down to +the statement after the labeled loop. In the example, execution starts again +with the statement `$a = $c`. + +You can nest many labeled loops, as shown in the following example. + +```powershell +:red while () { + :yellow while () { + while () { + if ($a) {break} + if ($b) {break red} + if ($c) {break yellow} + } + Write-Host "After innermost loop" + } + Write-Host "After yellow loop" +} +Write-Host "After red loop" +``` + +If the `$b` variable evaluates to True, execution of the script resumes after +the loop that is labeled "red". If the `$c` variable evaluates to True, +execution of the script control resumes after the loop that is labeled +"yellow". + +If the `$a` variable evaluates to True, execution resumes after the innermost +loop. No label is needed. + +PowerShell does not limit how far labels can resume execution. The label can +even pass control across script and function call boundaries. + +## Using `break` in a `switch` statement + +In a `switch`construct, `break` causes PowerShell to exit the `switch` code block. + +The `break` keyword is used to leave the `switch` construct. For example, the +following `switch` statement uses `break` statements to test for the most +specific condition: + +```powershell +$var = "word2" +switch -regex ($var) { + "word2" { + Write-Host "Exact" $_ + break + } + + "word.*" { + Write-Host "Match on the prefix" $_ + break + } + + "w.*" { + Write-Host "Match on at least the first letter" $_ + break + } + + default { + Write-Host "No match" $_ + break + } +} +``` + +In this example, the `$var` variable is created and initialized to a string +value of `word2`. The `switch` statement uses the **Regex** class to match the +variable value first with the term `word2`. Because the variable value and the +first test in the `switch` statement match, the first code block in the +`switch` statement runs. + +When PowerShell reaches the first `break` statement, the `switch` statement +exits. If the four `break` statements are removed from the example, all four +conditions are met. This example uses the `break` statement to display results +when the most specific condition is met. + +## Using `break` in a `trap` statement + +If the final statement executed in the body of a `trap` statement is `break`, +the error object is suppressed and the exception is re-thrown. + +The following example creates a **DivideByZeroException** exception that is +trapped using the `trap` statement. + +```powershell +function test { + trap [DivideByZeroException] { + Write-Host 'divide by zero trapped' + break + } + + $i = 3 + 'Before loop' + while ($true) { + "1 / $i = " + (1 / $i--) + } + 'After loop' +} +test +``` + +Notice that execution stops at the exception. The `After loop` is never reached. +The exception is re-thrown after the `trap` executes. + +```Output +Before loop +1 / 3 = 0.333333333333333 +1 / 2 = 0.5 +1 / 1 = 1 +divide by zero trapped +ParentContainsErrorRecordException: +Line | + 10 | "1 / $i = " + (1 / $i--) + | ~~~~~~~~~~~~~~~~~~~~~~~~ + | Attempted to divide by zero. +``` + +## Do not use `break` outside of a loop, `switch`, or `trap` + +When `break` is used outside of a construct that directly supports it +(loops, `switch`, `trap`), PowerShell looks _up the call stack_ for an +enclosing construct. If it can't find an enclosing construct, the current +runspace is quietly terminated. + +This means that functions and scripts that inadvertently use a `break` outside +of an enclosing construct that supports it can inadvertently terminate their +_callers_. + +Using `break` inside a pipeline `break`, such as a `ForEach-Object` script +block, not only exits the pipeline, it potentially terminates the entire +runspace. + +## See also + +- [about_Comparison_Operators](about_Comparison_Operators.md) +- [about_Continue](about_Continue.md) +- [about_For](about_For.md) +- [about_Foreach](about_Foreach.md) +- [about_Switch](about_Switch.md) +- [about_Throw](about_Throw.md) +- [about_Trap](about_Trap.md) +- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) +- [about_While](about_While.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Built-in_Functions.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Built-in_Functions.md new file mode 100644 index 000000000000..a07f61916d84 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Built-in_Functions.md @@ -0,0 +1,96 @@ +--- +description: Describes the built-in functions in PowerShell. +Locale: en-US +ms.date: 08/14/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_built-in_functions?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Built-in_Functions +--- +# about_Built-in_Functions + +## Short description + +Describes the built-in functions in PowerShell. + +## Long description + +PowerShell includes a set of functions that are loaded into every PowerShell +session. These functions are similar to cmdlets but they're not included in any +module. They're defined in the PowerShell engine itself. + +These functions are provided as shorthand helpers for common tasks. In many +cases, these functions call an existing cmdlet with an additional parameter. + +## `cd..` + +In the Windows CMD shell it's common to run the `cd` command without any spaces +between the command and the destination path. This function runs +`Set-Location ..` to change to the parent folder. + +## `cd\` + +In the Windows CMD shell it's common to run the `cd` command without any spaces +between the command and the destination path. This function runs +`Set-Location \` to change to the root folder. + +## `cd~` + +In the Windows CMD shell it's common to run the `cd` command without any spaces +between the command and the destination path. This function runs +`Set-Location ~` to change to home folder. + +This function was added in PowerShell 7.4. + +## `Pause` + +This function replicates the behavior of the `pause` command from `cmd.exe`. +The script pauses execution and prompts the user to hit a key to continue. + +## `help` + +This function invokes `Get-Help` with your parameters and passes the output to +the system's pager command. PowerShell uses a different default pager for +Windows and non-Windows systems. On Windows systems, the default pager is +`more.com`. On non-Windows systems, the default pager is `less`. + +If the `$env:PAGER` environment variable is defined, PowerShell uses the +specified program instead of the system default. + +## `prompt` + +This is the function that creates the default prompt for the PowerShell command +line. You can customize your prompt by overriding this function with your own. +For more information see [about_Prompts](about_Prompts.md). + +## `Clear-Host` + +This function clears the screen. For more information, see +[Clear-Host](xref:Microsoft.PowerShell.Core.Clear-Host). + +## `TabExpansion2` + +This is the default function to use for tab expansion. For more information, see +[TabExpansion2](xref:Microsoft.PowerShell.Core.TabExpansion2). + +## `oss` + +This function provides a short hand way to run `Out-String -Stream` in a +pipeline. For more information, see +[Out-String](xref:Microsoft.PowerShell.Utility.Out-String). + +## `mkdir` + +This function provides a short hand way to run `New-Item -Type Directory` with +your parameters. This function is only defined for Windows systems. Linux and +macOS system use the native `mkdir` command. + +## Windows drive letter functions + +In Windows, drive mount points are associated with a drive letter like `C:`. +You can switch to the current location on another drive just by entering that +drive letter on the command line. + +PowerShell create a function for every possible drive letter, `A:` through +`Z:`. + +These drive letter functions aren't defined on non-Windows systems. diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Calculated_Properties.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Calculated_Properties.md new file mode 100644 index 000000000000..34eca8daadc4 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Calculated_Properties.md @@ -0,0 +1,531 @@ +--- +description: PowerShell provides the ability to dynamically add new properties and alter the formatting of objects output to the pipeline. +Locale: en-US +ms.date: 09/03/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_calculated_properties?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Calculated_Properties +--- +# about_Calculated_Properties + +## Short description + +PowerShell provides the ability to dynamically add new properties and alter +the formatting of objects output to the pipeline. + +## Long description + +Several PowerShell cmdlets transform, group, or process input objects into +output objects using parameters that allow the addition of new properties to +those output objects. You can use these parameters to generate new, calculated +properties on output objects based on the values of input objects. The +calculated property is defined by a [hashtable][03] containing key-value pairs +that specify the name of the new property, an expression to calculate the +value, and optional formatting information. + +## Supported cmdlets + +The following cmdlets support calculated property values for the **Property** +parameter. The `Format-*` cmdlets also support calculated values for the +**GroupBy** parameter. + +The following list itemizes the cmdlets that support calculated properties and +the key-value pairs that each cmdlet supports. + +- `Compare-Object` + - `expression` + +- `ConvertTo-Html` + - `name`/`label` - optional (added in PowerShell 6.x) + - `expression` + - `width` - optional + - `alignment` - optional + +- `Format-Custom` + - `expression` + - `depth` - optional + +- `Format-List` + - `name`/`label` - optional + - `expression` + - `formatstring` - optional + + This same set of key-value pairs also apply to calculated property values + passed to the **GroupBy** parameter for all `Format-*` cmdlets. + +- `Format-Table` + - `name`/`label` - optional + - `expression` + - `formatstring` - optional + - `width` - optional + - `alignment` - optional + +- `Format-Wide` + - `expression` + - `formatstring` - optional + +- `Group-Object` + - `expression` + +- `Measure-Object` + - Only supports a script block for the expression, not a hashtable. + - Not supported in PowerShell 5.1 and older. + +- `Select-Object` + - `name`/`label` - optional + - `expression` + +- `Sort-Object` + - `expression` + - `ascending`/`descending` - optional + +> [!NOTE] +> The value of the `expression` can be a script block instead of a +> hashtable. For more information, see the [Notes][02] section. + +## Hashtable key definitions + +- `name`/`label` - Specifies the name of the property being created. You can + use `name` or its alias, `label`, interchangeably. +- `expression` - A string or script block used to calculate the value of the + new property. If the `expression` is a string, the value is interpreted as a + property name on the input object. This is a shorter option than + `expression = { $_. }`. +- `alignment` - Used by cmdlets that produce tabular output to define how the + values are displayed in a column. The value must be `'left'`, `'center'`, or + `'right'`. +- `formatstring` - Specifies a format string that defines how the value is + formatted for output. For more information about format strings, see + [Format types in .NET][01]. +- `width` - Specifies the maximum width column in a table when the value is + displayed. The value must be greater than `0`. +- `depth` - The **Depth** parameter of `Format-Custom` specifies the depth of + expansion for all properties. The `depth` key allows you to specify the + depth of expansion per property. +- `ascending` / `descending` - Allows you to specify the order of sorting for + one or more properties. These are boolean values. + +You don't need to spell out the hashtable keys as long as the specified name +prefix is unambiguous. For example, you can use `n` instead of `Name` and `e` +instead of `Expression`. + +## Examples + +### Compare-Object + +With calculated properties, you can control how the properties of the input +objects are compared. In this example, rather than comparing the values +directly, the values are compared to the result of the arithmetic operation +(modulus of 2). + +```powershell +Compare-Object @{p=1} @{p=2} -property @{ Expression = { $_.p % 2 } } +``` + +```Output + $_.p % 2 SideIndicator +---------- ------------- + 0 => + 1 <= +``` + +### ConvertTo-Html + +`ConvertTo-Html` can convert a collection of objects to an HTML table. +Calculated properties allow you to control how the table is presented. + +```powershell +Get-Alias | + ConvertTo-Html Name, + Definition, + @{ + name='ParameterCount' + expr={$_.Parameters.Keys.Count} + align='center' + } | + Out-File .\aliases.htm -Force +``` + +This example creates an HTML table containing a list of PowerShell aliases and +the number parameters for each aliased command. The values of +**ParameterCount** column are centered. + +### Format-Custom + +`Format-Custom` provides a custom view of an object in a format similar to a +class definition. More complex objects can contain members that are deeply +nested with complex types. The **Depth** parameter of `Format-Custom` specifies +the depth of expansion for all properties. The `depth` key allows you to +specify the depth of expansion per property. + +In this example, the `depth` key simplifies the custom output for the +`Get-Date` cmdlet. `Get-Date` returns a **DateTime** object. The **Date** +property of this object is also a **DateTime** object, so the object is nested. + +```powershell +Get-Date | Format-Custom @{expr={$_.Date};depth=1},TimeOfDay +``` + +```Output +class DateTime +{ + $_.Date = + class DateTime + { + Date = 8/7/2020 12:00:00 AM + Day = 7 + DayOfWeek = Friday + DayOfYear = 220 + Hour = 0 + Kind = Local + Millisecond = 0 + Minute = 0 + Month = 8 + Second = 0 + Ticks = 637323552000000000 + TimeOfDay = 00:00:00 + Year = 2020 + DateTime = Friday, August 07, 2020 12:00:00 AM + } + TimeOfDay = + class TimeSpan + { + Ticks = 435031592302 + Days = 0 + Hours = 12 + Milliseconds = 159 + Minutes = 5 + Seconds = 3 + TotalDays = 0.503508787386574 + TotalHours = 12.0842108972778 + TotalMilliseconds = 43503159.2302 + TotalMinutes = 725.052653836667 + TotalSeconds = 43503.1592302 + } +} +``` + +### Format-List + +In this example, we use calculated properties to change the name and format of +the output from `Get-ChildItem`. + +```powershell +Get-ChildItem *.json -File | + Format-List Fullname, + @{ + name='Modified' + expression={$_.LastWriteTime} + formatstring='O' + }, + @{ + name='Size' + expression={$_.Length/1KB} + formatstring='N2' + } +``` + +```Output +FullName : C:\Git\PS-Docs\PowerShell-Docs\.markdownlint.json +Modified : 2020-07-23T10:26:28.4092457-07:00 +Size : 2.40 + +FullName : C:\Git\PS-Docs\PowerShell-Docs\.openpublishing.publish.config.json +Modified : 2020-07-23T10:26:28.4092457-07:00 +Size : 2.25 + +FullName : C:\Git\PS-Docs\PowerShell-Docs\.openpublishing.redirection.json +Modified : 2020-07-27T13:05:24.3887629-07:00 +Size : 324.60 +``` + +### Format-Table + +In this example, the calculated property adds a **Type** property used to +classify the files by the content type. + +```powershell +Get-ChildItem -File | + Sort-Object extension | + Format-Table Name, Length -GroupBy @{ + name='Type' + expression={ + switch ($_.extension) { + '.md' {'Content'} + '' {'Metacontent'} + '.ps1' {'Automation'} + '.yml' {'Automation'} + default {'Configuration'} + } + } + } +``` + +```Output + Type: Metacontent + +Name Length +---- ------ +ThirdPartyNotices 1229 +LICENSE-CODE 1106 +LICENSE 19047 + + Type: Configuration + +Name Length +---- ------ +.editorconfig 183 +.gitattributes 419 +.gitignore 228 +.markdownlint.json 2456 +.openpublishing.publish.config.json 2306 +.openpublishing.redirection.json 332394 +.localization-config 232 + + Type: Content + +Name Length +---- ------ +README.md 3355 +CONTRIBUTING.md 247 + + Type: Automation + +Name Length +---- ------ +.openpublishing.build.ps1 796 +build.ps1 7495 +ci.yml 645 +ci-steps.yml 2035 +daily.yml 1271 +``` + +### Format-Wide + +The `Format-Wide` cmdlet allows you to display the value of one property for +objects in a collection as a multi-column list. + +For this example, we want to see the filename and the size (in kilobytes) as a +wide listing. Since `Format-Wide` doesn't display more than one property, we +use a calculated property to combine the value of two properties into a single +value. + +```powershell +Get-ChildItem -File | + Format-Wide -Property @{e={'{0} ({1:N2}kb)' -f $_.name,($_.length/1kb)}} +``` + +```Output +.editorconfig (0.18kb) .gitattributes (0.41kb) +.gitignore (0.22kb) .localization-config (0.23kb) +.markdownlint.json (2.40kb) .openpublishing.build.ps1 (0.78kb) +.openpublishing.publish.config.json (2.25kb) .openpublishing.redirection.json (324.60kb) +build.ps1 (7.32kb) ci.yml (0.63kb) +ci-steps.yml (1.99kb) CONTRIBUTING.md (0.24kb) +daily.yml (1.24kb) LICENSE (18.60kb) +LICENSE-CODE (1.08kb) README.md (3.28kb) +ThirdPartyNotices (1.20kb) +``` + +### Group-Object + +The `Group-Object` cmdlet displays objects in groups based on the value of a +specified property. In this example, the calculated property counts the number +of files of each content type. + +```powershell +Get-ChildItem -File | + Sort-Object extension | + Group-Object -NoElement -Property @{ + expression={ + switch ($_.extension) { + '.md' {'Content'} + '' {'Metacontent'} + '.ps1' {'Automation'} + '.yml' {'Automation'} + default {'Configuration'} + } + } + } +``` + +```Output +Count Name +----- ---- + 5 Automation + 7 Configuration + 2 Content + 3 Metacontent +``` + +### Measure-Object + +The `Measure-Object` cmdlet calculates the numeric properties of objects. In +this example, we use a calculated property to get the count of the numbers +between 1 and 10 that are evenly divisible by 3. + +The script block returns `$true` if the number is divisible by 3 and `$false` +for all other numbers. The **Sum** operation treats `$true` values as `1` and +`$false` values as `0`. + +```powershell +1..10 | Measure-Object -Property {($_ % 3) -eq 0} -Sum +``` + +```Output +Count : 10 +Average : +Sum : 3 +Maximum : +Minimum : +StandardDeviation : +Property : ($_ % 3) -eq 0 +``` + +> [!NOTE] +> Unlike the other cmdlets, `Measure-Object` doesn't accept a hashtable for +> calculated properties. You must use a script block. + +### Select-Object + +You can use calculated properties to add additional members to the objects +output with the `Select-Object` cmdlet. In this example, we're listing the +PowerShell aliases that begin with the letter `C`. Using `Select-Object`, we +output the alias, the cmdlet it's mapped to, and a count for the number of +parameters defined for the cmdlet. Using a calculated property, we can create +the **ParameterCount** property. + +```powershell +$aliases = Get-Alias c* | + Select-Object Name, + Definition, + @{ + name='ParameterCount' + expr={$_.Parameters.Keys.Count} + } +$aliases | Get-Member +$aliases +``` + +```Output + TypeName: Selected.System.Management.Automation.AliasInfo + +Name MemberType Definition +---- ---------- ---------- +Equals Method bool Equals(System.Object obj) +GetHashCode Method int GetHashCode() +GetType Method type GetType() +ToString Method string ToString() +Definition NoteProperty string Definition=Get-Content +Name NoteProperty string Name=cat +ParameterCount NoteProperty System.Int32 ParameterCount=21 + +Name Definition ParameterCount +---- ---------- -------------- +cat Get-Content 21 +cd Set-Location 15 +cdd Push-MyLocation 1 +chdir Set-Location 15 +clc Clear-Content 20 +clear Clear-Host 0 +clhy Clear-History 17 +cli Clear-Item 20 +clp Clear-ItemProperty 22 +cls Clear-Host 0 +clv Clear-Variable 19 +cnsn Connect-PSSession 29 +compare Compare-Object 20 +copy Copy-Item 24 +cp Copy-Item 24 +cpi Copy-Item 24 +cpp Copy-ItemProperty 23 +cvpa Convert-Path 13 +``` + +### Sort-Object + +Using the calculated properties, you can sort data in different orders per +property. This example sorts data from a CSV file in ascending order by +**Date**. But within each date, it sorts the rows in descending order by +**UnitsSold**. + +```powershell +Import-Csv C:\temp\sales-data.csv | + Sort-Object Date, @{expr={$_.UnitsSold}; desc=$true}, Salesperson | + Select-Object Date, Salesperson, UnitsSold +``` + +```Output +Date Salesperson UnitsSold +---- ----------- --------- +2020-08-01 Sally 3 +2020-08-01 Anne 2 +2020-08-01 Fred 1 +2020-08-02 Anne 6 +2020-08-02 Fred 2 +2020-08-02 Sally 0 +2020-08-03 Anne 5 +2020-08-03 Sally 3 +2020-08-03 Fred 1 +2020-08-04 Anne 2 +2020-08-04 Fred 2 +2020-08-04 Sally 2 +``` + +## Notes + +- You may specify the expression script block _directly_, as an argument, + rather than specifying it as the `Expression` entry in a hashtable. For + example: + + ```powershell + '1', '10', '2' | Sort-Object { [int] $_ } + ``` + + This example is convenient for cmdlets that don't require (or support) + naming a property via the `Name` key, such as `Sort-Object`, `Group-Object`, + and `Measure-Object`. + + For cmdlets that support naming the property, the script block is converted + to a string and used as the name of the property in the output. + +- `Expression` script blocks run in _child_ scopes, meaning that the caller's + variables can't be directly modified. + +- Pipeline logic is applied to the output from `Expression` script blocks. This + means that outputting a single-element array causes that array to be + unwrapped. + +- For most cmdlets, errors inside expression script blocks are quietly ignored. + For `Sort-Object`, statement-terminating and script-terminating errors are + _output_ but they don't terminate the statement. + +## See also + +- [about_Hash_Tables][03] +- [ConvertTo-Html][05] +- [Format-Custom][06] +- [Format-List][07] +- [Format-Table][08] +- [Format-Wide][09] +- [Compare-Object][04] +- [Group-Object][10] +- [Measure-Object][11] +- [Select-Object][12] +- [Sort-Object][13] +- [Format types in .NET][01] + + +[01]: /dotnet/standard/base-types/formatting-types +[02]: #notes +[03]: about_hash_tables.md +[04]: xref:Microsoft.PowerShell.Utility.Compare-Object +[05]: xref:Microsoft.PowerShell.Utility.ConvertTo-Html +[06]: xref:Microsoft.PowerShell.Utility.Format-Custom +[07]: xref:Microsoft.PowerShell.Utility.Format-List +[08]: xref:Microsoft.PowerShell.Utility.Format-Table +[09]: xref:Microsoft.PowerShell.Utility.Format-Wide +[10]: xref:Microsoft.PowerShell.Utility.Group-Object +[11]: xref:Microsoft.PowerShell.Utility.Measure-Object +[12]: xref:Microsoft.PowerShell.Utility.Select-Object +[13]: xref:Microsoft.PowerShell.Utility.Sort-Object diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Calling_Generic_Methods.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Calling_Generic_Methods.md new file mode 100644 index 000000000000..2bc88d87cfac --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Calling_Generic_Methods.md @@ -0,0 +1,90 @@ +--- +description: Describes how to call generic methods of .NET types in PowerShell +Locale: en-US +ms.date: 02/02/2022 +schema: 2.0.0 +title: about_Calling_Generic_Methods +--- +# about_Calling_Generic_Methods + +Generics let you tailor a method, class, structure, or interface to the precise +data type it acts upon. For example, instead of using the + class, which allows keys and values to be +of any type, you can use the +generic class and specify the types allowed for the **key** and **value** +properties. Generics provide increased code reusability and type safety. + +For some generic methods, PowerShell is able to figure out generic arguments +for a method by inferring from the provided arguments. However, method +resolution can be complicated when a method has both generic and non-generic +overloads, or when the generic method takes no formal parameter. PowerShell can +fail to resolve the correct method without the explicit generic method +arguments. + +For example, `[Array]::Empty()`. The .NET **Array** class has a static, +generic method `Empty()` that takes no formal parameters. + +Prior to PowerShell 7.3, to ensure proper method resolution you had to use +complicated workarounds using .NET reflection. For an example, see Lee Holmes' +blog post +[Invoking generic methods on non-generic classes in PowerShell](https://www.leeholmes.com/invoking-generic-methods-on-non-generic-classes-in-powershell/). + +Beginning with PowerShell 7.3, you can specify the types for a generic method. + +## Syntax + +A generic method is a method with two parameter lists: a list of generic types +and a list of method arguments. + +The following examples show the new PowerShell syntax for accessing a generic +method: + +```Syntax +# static generic methods +[type_name]::MethodName[generic_type_arguments](method_arguments) + +# instance generic methods +$object.MethodName[generic_type_arguments](method_arguments) +``` + +The `generic_type_arguments` can be a single type or comma-separated list of +types, like `[string, int]`, including other generic types like +`$obj.MethodName[string, System.Collections.Generic.Dictionary[string, int]]()` + +The `method_arguments` can be zero or more items. + +For more information, see [Generics in .NET](/dotnet/standard/generics/). + +## Example + +In this example, we create a list of integers then use the +`System.Linq.Enumerable` class to enumerate the values and transform them to a +new value. + +The variable `$list` is a generic `List` object that can only contain +integers. `List` is a generic class that allows you to specify the type of +its members when you create it. +`[System.Linq.Enumerable]::Select(T1,T2)` is a generic method that +require two generic type parameters and two formal value parameters. + +```powershell +[System.Collections.Generic.List[int]]$list = @( 1, 2, 3, 4, 5 ) +$result = [System.Linq.Enumerable]::Select[int, float]( + $list, + [Func[int, float]]{ + param($item) + [math]::Pow($item, 3) + } +) +$result +``` + +The output shows each value raised to the power of 3. + +```Output +1 +8 +27 +64 +125 +``` diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md new file mode 100644 index 000000000000..8704f3494aba --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md @@ -0,0 +1,48 @@ +--- +description: This article explains how PowerShell handles case-sensitivity. +Locale: en-US +ms.custom: wiki-migration +ms.date: 06/06/2022 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-7.6&WT.mc_id=ps-gethelp +title: about_Case-Sensitivity +--- +# about_Case-Sensitivity + +## Short description + +PowerShell is as case-insensitive as possible while preserving case. + +## Long description + +As a general principle, PowerShell is as case insensitive as possible while preserving case and not +breaking the underlying OS. + +### On Unix-based systems + +On Unix-based systems, PowerShell is case-sensitive because filesystem manipulation and environment +variables directly affect the underlying operating system and integration with other tools. + +## On all systems + +- PowerShell variables are case-insensitive + + Variable names have no interaction between them and the underlying operating system. PowerShell + treats them case-insensitively. + +- Module names are case-insensitive (with exceptions) + + The _name_ of the module is purely a PowerShell concept and treated case-insensitively. However, there + is a strong mapping to a foldername, which can be case-sensitive in the underlying operating + system. Importing two modules with the same case-insensitive name has the same behavior as + importing two modules with the same name from different paths. + + The name of a module is stored in the session state using the case by which it was imported. The + name, as stored in the session state, is used by `Update-Help` when looking for new help files. + The web service that serves the help files for Microsoft uses a case-sensitive filesystem. When + the case of the imported name of the module doesn't match, `Update-Help` can't find the help files + and reports an error. + +## Related links + +- [about_Environment_Variables](about_environment_variables.md) +- [Import-Module](xref:Microsoft.PowerShell.Core.Import-Module) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Character_Encoding.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Character_Encoding.md new file mode 100644 index 000000000000..8d29d357cf2a --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Character_Encoding.md @@ -0,0 +1,234 @@ +--- +description: Describes how PowerShell uses character encoding for input and output of string data. +Locale: en-US +ms.date: 03/09/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Character_Encoding +--- +# about_Character_Encoding + +## Short description + +Describes how PowerShell uses character encoding for input and output of string +data. + +## Long description + +Unicode is a worldwide character-encoding standard. The system uses Unicode +exclusively for character and string manipulation. For a detailed description +of all aspects of Unicode, refer to +[The Unicode Standard](https://www.unicode.org/standard/standard.html). + +Windows supports Unicode and traditional character sets. Traditional character +sets, such as Windows code pages, use 8-bit values or combinations of 8-bit +values to represent the characters used in a specific language or geographical +region settings. + +PowerShell uses a Unicode character set by default. However, several cmdlets +have an **Encoding** parameter that can specify encoding for a different +character set. This parameter allows you to choose the specific the character +encoding you need for interoperability with other systems and applications. + +The following cmdlets have the **Encoding** parameter: + +- Microsoft.PowerShell.Management + - Add-Content + - Get-Content + - Set-Content +- Microsoft.PowerShell.Utility + - Export-Clixml + - Export-Csv + - Export-PSSession + - Format-Hex + - Import-Csv + - Out-File + - Select-String + - Send-MailMessage + +## The byte-order-mark + +The byte-order-mark (BOM) is a _Unicode signature_ in the first few bytes of a +file or text stream that indicate which Unicode encoding used for the data. For +more information, see the +[Byte order mark](/globalization/encoding/byte-order-mark) documentation. + +In Windows PowerShell, any Unicode encoding, except `UTF7`, always creates a +BOM. PowerShell (v6 and higher) defaults to `utf8NoBOM` for all text output. + +For best overall compatibility, avoid using BOMs in UTF-8 files. Unix platforms +and Unix-heritage utilities also used on Windows Platforms don't support BOMs. + +Similarly, `UTF7` encoding should be avoided. UTF-7 is not a standard Unicode +encoding and is written without a BOM in all versions of PowerShell. + +Creating PowerShell scripts on a Unix-like platform or using a cross-platform +editor on Windows, such as Visual Studio Code, results in a file encoded using +`UTF8NoBOM`. These files work fine in PowerShell, but may break in Windows +PowerShell if the file contains non-Ascii characters. + +If you need to use non-Ascii characters in your scripts, save them as UTF-8 +with BOM. Without the BOM, Windows PowerShell misinterprets your script as +being encoded in the legacy "ANSI" codepage. Conversely, files that do have the +UTF-8 BOM can be problematic on Unix-like platforms. Many Unix tools such as +`cat`, `sed`, `awk`, and some editors such as `gedit` don't know how to treat +the BOM. + +## Character encoding in Windows PowerShell + +In PowerShell 5.1, the **Encoding** parameter supports the following values: + +- `Ascii` Uses Ascii (7-bit) character set. +- `BigEndianUnicode` Uses UTF-16 with the big-endian byte order. +- `BigEndianUTF32` Uses UTF-32 with the big-endian byte order. +- `Byte` Encodes a set of characters into a sequence of bytes. +- `Default` Uses the encoding that corresponds to the system's active code page + (usually ANSI). +- `Oem` Uses the encoding that corresponds to the system's current OEM code + page. +- `String` Same as `Unicode`. +- `Unicode` Uses UTF-16 with the little-endian byte order. +- `Unknown` Same as `Unicode`. +- `UTF32` Uses UTF-32 with the little-endian byte order. +- `UTF7` Uses UTF-7. +- `UTF8` Uses UTF-8 (with BOM). + +In general, Windows PowerShell uses the Unicode +[UTF-16LE](https://wikipedia.org/wiki/UTF-16) encoding by default. However, +the default encoding used by cmdlets in Windows PowerShell is not consistent. + +> [!NOTE] +> Using any Unicode encoding, except `UTF7`, always creates a BOM. + +For cmdlets that write output to files: + +- `Out-File` and the redirection operators `>` and `>>` create UTF-16LE, which + notably differs from `Set-Content` and `Add-Content`. + +- `New-ModuleManifest` and `Export-CliXml` also create UTF-16LE files. + +- When the target file is empty or doesn't exist, `Set-Content` and + `Add-Content` use `Default` encoding. `Default` is the encoding specified by + the active system locale's ANSI legacy code page. + +- `Export-Csv` creates `Ascii` files but uses different encoding when using + **Append** parameter (see below). + +- `Export-PSSession` creates UTF-8 files with BOM by default. + +- `New-Item -Type File -Value` creates a BOM-less UTF-8 file. + +- `Send-MailMessage` uses `Ascii` encoding by default. + +- `Start-Transcript` creates `Utf8` files with a BOM. When the **Append** + parameter is used, the encoding can be different (see below). + +For commands that append to an existing file: + +- `Out-File -Append` and the `>>` redirection operator make no attempt to match + the encoding of the existing target file's content. Instead, they use the + default encoding unless the **Encoding** parameter is used. You must use the + files original encoding when appending content. + +- In the absence of an explicit **Encoding** parameter, `Add-Content` detects + the existing encoding and automatically applies it to the new content. If the + existing content has no BOM, `Default` ANSI encoding is used. The behavior of + `Add-Content` is the same in PowerShell (v6 and higher) except the default + encoding is `Utf8`. + +- `Export-Csv -Append` matches the existing encoding when the target file + contains a BOM. In the absence of a BOM, it uses `Utf8` encoding. + +- `Start-Transcript -Append` matches the existing encoding of files that + include a BOM. In the absence of a BOM, it defaults to `Ascii` encoding. This + encoding can result in data loss or character corruption when the data in the + transcript contains multibyte characters. + +For cmdlets that read string data in the absence of a BOM: + +- `Get-Content` and `Import-PowerShellDataFile` uses the `Default` ANSI + encoding. ANSI is also what the PowerShell engine uses when it reads source + code from files. + +- `Import-Csv`, `Import-CliXml`, and `Select-String` assume `Utf8` in the + absence of a BOM. + +## Character encoding in PowerShell + +In PowerShell (v7.1 and higher), the **Encoding** parameter supports the +following values: + +- `ascii`: Uses the encoding for the ASCII (7-bit) character set. +- `ansi`: Uses the encoding for the for the current culture's ANSI code page. + This option was added in PowerShell 7.4. +- `bigendianunicode`: Encodes in UTF-16 format using the big-endian byte order. +- `bigendianutf32`: Encodes in UTF-32 format using the big-endian byte order. +- `oem`: Uses the default encoding for MS-DOS and console programs. +- `unicode`: Encodes in UTF-16 format using the little-endian byte order. +- `utf7`: Encodes in UTF-7 format. +- `utf8`: Encodes in UTF-8 format (no BOM). +- `utf8BOM`: Encodes in UTF-8 format with Byte Order Mark (BOM) +- `utf8NoBOM`: Encodes in UTF-8 format without Byte Order Mark (BOM) +- `utf32`: Encodes in UTF-32 format using the little-endian byte order. + +PowerShell defaults to `utf8NoBOM` for all output. + +Beginning with PowerShell 6.2, the **Encoding** parameter also allows numeric +IDs of registered code pages (like `-Encoding 1251`) or string names of +registered code pages (like `-Encoding "windows-1251"`). For more information, +see the .NET documentation for +[Encoding.CodePage](/dotnet/api/system.text.encoding.codepage). + +Starting with PowerShell 7.4, you can use the `Ansi` value for the **Encoding** +parameter to pass the numeric ID for the current culture's ANSI code page +without having to specify it manually. + +## Changing the default encoding + +PowerShell has two default variables that can be used to change the default +encoding behavior. + +- `$PSDefaultParameterValues` +- `$OutputEncoding` + +For more information, see +[about_Preference_Variables](about_Preference_Variables.md). + +Beginning in PowerShell 5.1, the redirection operators (`>` and `>>`) call the +`Out-File` cmdlet. Therefore, you can set the default encoding of them using +the `$PSDefaultParameterValues` preference variable as shown in this example: + +```powershell +$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8' +``` + +Use the following statement to change the default encoding for all cmdlets that +have the **Encoding** parameter. + +```powershell +$PSDefaultParameterValues['*:Encoding'] = 'utf8' +``` + +> [!IMPORTANT] +> Putting this command in your PowerShell profile makes the preference a +> session-global setting that affects all commands and scripts that do not +> explicitly specify an encoding. +> +> Similarly, you should include such commands in your scripts or modules that +> you want to behave the same way. Using these commands ensure that cmdlets +> behave the same way even when run by another user, on a different computer, +> or in a different version of PowerShell. + +The automatic variable `$OutputEncoding` affects the encoding PowerShell uses +to communicate with external programs. It has no effect on the encoding that +the output redirection operators and PowerShell cmdlets use to save to files. + +## See also + +- [about_Preference_Variables](about_Preference_Variables.md) +- [Byte order mark](https://wikipedia.org/wiki/Byte_order_mark) +- [Code Pages - Win32 apps](/windows/win32/intl/code-pages) +- [Encoding.CodePage](/dotnet/api/system.text.encoding.codepage) +- [Introduction to character encoding in .NET](/dotnet/standard/base-types/character-encoding-introduction) +- [The Unicode Standard](https://www.unicode.org/standard/standard.html) +- [UTF-16LE](https://wikipedia.org/wiki/UTF-16) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CimSession.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CimSession.md new file mode 100644 index 000000000000..2ee310c6c102 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CimSession.md @@ -0,0 +1,71 @@ +--- +description: Describes a **CimSession** object and the difference between CIM sessions and PowerShell sessions. +Locale: en-US +ms.date: 03/07/2022 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_cimsession?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_CimSession +--- +# about_CimSession + +## Short description + +Describes a **CimSession** object and the difference between CIM sessions and +PowerShell sessions. + +## Long description + +> This information only applies to PowerShell running on Windows. + +A Common Information Model (CIM) session is a client-side object that +represents a connection to a local computer or a remote computer. You can use +CIM sessions as an alternative to PowerShell sessions (PSSessions). Both +approaches have advantages. + +You can use the `New-CimSession` cmdlet on a Windows computer to create a CIM +session that contains information about a connection, such as computer name, +the protocol used for the connection, session ID, and instance ID. + +After you create a **CimSession** object that specifies information required to +establish a connection, PowerShell does not establish the connection +immediately. When a cmdlet uses the CIM session, PowerShell connects to the +specified computer, and then, when the cmdlet finishes, PowerShell terminates +the connection. + +If you create a **PSSession** instead of using a CIM session, PowerShell +validates connection settings, and then establishes and maintains the +connection. If you use CIM sessions, PowerShell does not open a network +connection until needed. For more information about PowerShell sessions, see +[about_PSSessions](about_PSSessions.md). + +## When to use a CIM session + +Only cmdlets that work with a Windows Management Instrumentation (WMI) provider +or CIM over WS-Man accept CIM sessions. For other cmdlets, use **PSSessions**. + +When you use a CIM session, PowerShell runs the cmdlet on the local client. It +connects to the WMI provider using the CIM session. The target computer does +not require PowerShell, or even any version of the Windows operating system. + +In contrast, a cmdlet run using a **PSSession** runs on the target computer. +It requires PowerShell on the target system. Furthermore, the cmdlet sends data +back to the local computer. PowerShell manages the data sent over the +connection, and keeps the size within the limits set by Windows Remote +Management (WinRM). CIM sessions do not impose the WinRM limits. + +## Using CDXML cmdlets + +CIM-based Cmdlet Definition XML (CDXML) cmdlets can be written to use any WMI +Provider. All WMI providers use **CimSession** objects. For more information +about CDXML, see [CDXML definition and terms](/previous-versions/windows/desktop/wmi_v2/cdxml-overview). + +CDXML cmdlets have an automatic **CimSession** parameter that can take an array +of **CimSession** objects. By default, PowerShell limits number of concurrent +CIM Connections to 15. This limit can be overridden by CDXML cmdlets that +implement the **ThrottleLimit**. See the individual cmdlet documentation to +understand the **ThrottleLimit**. + +## See also + +- [about_PSSessions](about_PSSessions.md) +- [New-CimSession](xref:CimCmdlets.New-CimSession) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes.md new file mode 100644 index 000000000000..3e377982a0a3 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes.md @@ -0,0 +1,796 @@ +--- +description: Describes how you can use classes to create your own custom types. +Locale: en-US +ms.date: 01/23/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Classes +--- +# about_Classes + +## Short description + +Describes how you can use classes to create your own custom types. + +## Long description + +Starting with version 5.0, PowerShell has a formal syntax to define classes and +other user-defined types. The addition of classes enables developers and IT +professionals to embrace PowerShell for a wider range of use cases. + +A class declaration is a blueprint used to create instances of objects at run +time. When you define a class, the class name is the name of the type. For +example, if you declare a class named **Device** and initialize a variable +`$dev` to a new instance of **Device**, `$dev` is an object or instance of type +**Device**. Each instance of **Device** can have different values in its +properties. + +## Supported scenarios + +- Define custom types in PowerShell using object-oriented programming semantics + like classes, properties, methods, inheritance, etc. +- Define DSC resources and their associated types using the PowerShell + language. +- Define custom attributes to decorate variables, parameters, and custom type + definitions. +- Define custom exceptions that can be caught by their type name. + +## Syntax + +### Definition syntax + +Class definitions use the following syntax: + +```Syntax +class [: [][,]] { + [[] [hidden] [static] ...] + [([]) + {} ...] + [[] [hidden] [static] ...] +} +``` + +### Instantiation syntax + +To instantiate an instance of a class, use one of the following syntaxes: + +```Syntax +[$ =] New-Object -TypeName [ + [-ArgumentList] ] +``` + +```Syntax +[$ =] []::new([]) +``` + +```Syntax +[$ =] []@{[]} +``` + +> [!NOTE] +> When using the `[]::new()` syntax, brackets around the class name +> are mandatory. The brackets signal a type definition for PowerShell. +> +> The hashtable syntax only works for classes that have a default constructor +> that doesn't expect any parameters. It creates an instance of the class with +> the default constructor and then assigns the key-value pairs to the instance +> properties. If any key in the hashtable isn't a valid property name, +> PowerShell raises an error. + +## Examples + +### Example 1 - Minimal definition + +This example shows the minimum syntax needed to create a usable class. + +```powershell +class Device { + [string]$Brand +} + +$dev = [Device]::new() +$dev.Brand = "Fabrikam, Inc." +$dev +``` + +```Output +Brand +----- +Fabrikam, Inc. +``` + +### Example 2 - Class with instance members + +This example defines a **Book** class with several properties, constructors, +and methods. Every defined member is an _instance_ member, not a static member. +The properties and methods can only be accessed through a created instance of +the class. + +```powershell +class Book { + # Class properties + [string] $Title + [string] $Author + [string] $Synopsis + [string] $Publisher + [datetime] $PublishDate + [int] $PageCount + [string[]] $Tags + # Default constructor + Book() { $this.Init(@{}) } + # Convenience constructor from hashtable + Book([hashtable]$Properties) { $this.Init($Properties) } + # Common constructor for title and author + Book([string]$Title, [string]$Author) { + $this.Init(@{Title = $Title; Author = $Author }) + } + # Shared initializer method + [void] Init([hashtable]$Properties) { + foreach ($Property in $Properties.Keys) { + $this.$Property = $Properties.$Property + } + } + # Method to calculate reading time as 2 minutes per page + [timespan] GetReadingTime() { + if ($this.PageCount -le 0) { + throw 'Unable to determine reading time from page count.' + } + $Minutes = $this.PageCount * 2 + return [timespan]::new(0, $Minutes, 0) + } + # Method to calculate how long ago a book was published + [timespan] GetPublishedAge() { + if ( + $null -eq $this.PublishDate -or + $this.PublishDate -eq [datetime]::MinValue + ) { throw 'PublishDate not defined' } + + return (Get-Date) - $this.PublishDate + } + # Method to return a string representation of the book + [string] ToString() { + return "$($this.Title) by $($this.Author) ($($this.PublishDate.Year))" + } +} +``` + +The following snippet creates an instance of the class and shows how it +behaves. After creating an instance of the **Book** class, the example +uses the `GetReadingTime()` and `GetPublishedAge()` methods to write +a message about the book. + +```powershell +$Book = [Book]::new(@{ + Title = 'The Hobbit' + Author = 'J.R.R. Tolkien' + Publisher = 'George Allen & Unwin' + PublishDate = '1937-09-21' + PageCount = 310 + Tags = @('Fantasy', 'Adventure') +}) + +$Book +$Time = $Book.GetReadingTime() +$Time = @($Time.Hours, 'hours and', $Time.Minutes, 'minutes') -join ' ' +$Age = [Math]::Floor($Book.GetPublishedAge().TotalDays / 365.25) + +"It takes $Time to read $Book,`nwhich was published $Age years ago." +``` + +```Output +Title : The Hobbit +Author : J.R.R. Tolkien +Synopsis : +Publisher : George Allen & Unwin +PublishDate : 9/21/1937 12:00:00 AM +PageCount : 310 +Tags : {Fantasy, Adventure} + +It takes 10 hours and 20 minutes to read The Hobbit by J.R.R. Tolkien (1937), +which was published 86 years ago. +``` + +### Example 3 - Class with static members + +The **BookList** class in this example builds on the **Book** class in example +2. While the **BookList** class can't be marked static itself, the +implementation only defines the **Books** static property and a set of static +methods for managing that property. + +```powershell +class BookList { + # Static property to hold the list of books + static [System.Collections.Generic.List[Book]] $Books + # Static method to initialize the list of books. Called in the other + # static methods to avoid needing to explicit initialize the value. + static [void] Initialize() { [BookList]::Initialize($false) } + static [bool] Initialize([bool]$force) { + if ([BookList]::Books.Count -gt 0 -and -not $force) { + return $false + } + + [BookList]::Books = [System.Collections.Generic.List[Book]]::new() + + return $true + } + # Ensure a book is valid for the list. + static [void] Validate([book]$Book) { + $Prefix = @( + 'Book validation failed: Book must be defined with the Title,' + 'Author, and PublishDate properties, but' + ) -join ' ' + if ($null -eq $Book) { throw "$Prefix was null" } + if ([string]::IsNullOrEmpty($Book.Title)) { + throw "$Prefix Title wasn't defined" + } + if ([string]::IsNullOrEmpty($Book.Author)) { + throw "$Prefix Author wasn't defined" + } + if ([datetime]::MinValue -eq $Book.PublishDate) { + throw "$Prefix PublishDate wasn't defined" + } + } + # Static methods to manage the list of books. + # Add a book if it's not already in the list. + static [void] Add([Book]$Book) { + [BookList]::Initialize() + [BookList]::Validate($Book) + if ([BookList]::Books.Contains($Book)) { + throw "Book '$Book' already in list" + } + + $FindPredicate = { + param([Book]$b) + + $b.Title -eq $Book.Title -and + $b.Author -eq $Book.Author -and + $b.PublishDate -eq $Book.PublishDate + }.GetNewClosure() + if ([BookList]::Books.Find($FindPredicate)) { + throw "Book '$Book' already in list" + } + + [BookList]::Books.Add($Book) + } + # Clear the list of books. + static [void] Clear() { + [BookList]::Initialize() + [BookList]::Books.Clear() + } + # Find a specific book using a filtering scriptblock. + static [Book] Find([scriptblock]$Predicate) { + [BookList]::Initialize() + return [BookList]::Books.Find($Predicate) + } + # Find every book matching the filtering scriptblock. + static [Book[]] FindAll([scriptblock]$Predicate) { + [BookList]::Initialize() + return [BookList]::Books.FindAll($Predicate) + } + # Remove a specific book. + static [void] Remove([Book]$Book) { + [BookList]::Initialize() + [BookList]::Books.Remove($Book) + } + # Remove a book by property value. + static [void] RemoveBy([string]$Property, [string]$Value) { + [BookList]::Initialize() + $Index = [BookList]::Books.FindIndex({ + param($b) + $b.$Property -eq $Value + }.GetNewClosure()) + if ($Index -ge 0) { + [BookList]::Books.RemoveAt($Index) + } + } +} +``` + +Now that **BookList** is defined, the book from the previous example can be +added to the list. + +```powershell +$null -eq [BookList]::Books + +[BookList]::Add($Book) + +[BookList]::Books +``` + +```Output +True + +Title : The Hobbit +Author : J.R.R. Tolkien +Synopsis : +Publisher : George Allen & Unwin +PublishDate : 9/21/1937 12:00:00 AM +PageCount : 310 +Tags : {Fantasy, Adventure} +``` + +The following snippet calls the static methods for the class. + +```powershell +[BookList]::Add([Book]::new(@{ + Title = 'The Fellowship of the Ring' + Author = 'J.R.R. Tolkien' + Publisher = 'George Allen & Unwin' + PublishDate = '1954-07-29' + PageCount = 423 + Tags = @('Fantasy', 'Adventure') +})) + +[BookList]::Find({ + param ($b) + + $b.PublishDate -gt '1950-01-01' +}).Title + +[BookList]::FindAll({ + param($b) + + $b.Author -match 'Tolkien' +}).Title + +[BookList]::Remove($Book) +[BookList]::Books.Title + +[BookList]::RemoveBy('Author', 'J.R.R. Tolkien') +"Titles: $([BookList]::Books.Title)" + +[BookList]::Add($Book) +[BookList]::Add($Book) +``` + +```Output +The Fellowship of the Ring + +The Hobbit +The Fellowship of the Ring + +The Fellowship of the Ring + +Titles: + +Exception: +Line | + 84 | throw "Book '$Book' already in list" + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | Book 'The Hobbit by J.R.R. Tolkien (1937)' already in list +``` + +### Example 4 - Class definition with and without Runspace affinity + +The `ShowRunspaceId()` method of `[UnsafeClass]` reports different thread Ids +but the same runspace ID. Eventually, the session state is corrupted causing +an error, such as `Global scope cannot be removed`. + +```powershell +# Class definition with Runspace affinity (default behavior) +class UnsafeClass { + static [object] ShowRunspaceId($val) { + return [PSCustomObject]@{ + ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId + RunspaceId = [runspace]::DefaultRunspace.Id + } + } +} + +$unsafe = [UnsafeClass]::new() + +while ($true) { + 1..10 | ForEach-Object -Parallel { + Start-Sleep -ms 100 + ($using:unsafe)::ShowRunspaceId($_) + } +} +``` + +> [!NOTE] +> This example runs in an infinite loop. Enter Ctrl+C to +> stop the execution. + +The `ShowRunspaceId()` method of `[SafeClass]` reports different thread and +Runspace ids. + +```powershell +# Class definition with NoRunspaceAffinity attribute +[NoRunspaceAffinity()] +class SafeClass { + static [object] ShowRunspaceId($val) { + return [PSCustomObject]@{ + ThreadId = [Threading.Thread]::CurrentThread.ManagedThreadId + RunspaceId = [runspace]::DefaultRunspace.Id + } + } +} + +$safe = [SafeClass]::new() + +while ($true) { + 1..10 | ForEach-Object -Parallel { + Start-Sleep -ms 100 + ($using:safe)::ShowRunspaceId($_) + } +} +``` + +> [!NOTE] +> This example runs in an infinite loop. Enter Ctrl+C to +> stop the execution. + +## Class properties + +Properties are variables declared in the class scope. A property can be of any +built-in type or an instance of another class. Classes can have zero or more +properties. Classes don't have a maximum property count. + +For more information, see [about_Classes_Properties][01]. + +## Class methods + +Methods define the actions that a class can perform. Methods can take +parameters that specify input data. Methods always define an output type. If a +method doesn't return any output, it must have the **Void** output type. If a +method doesn't explicitly define an output type, the method's output type is +**Void**. + +For more information, see [about_Classes_Methods][02]. + +## Class constructors + +Constructors enable you to set default values and validate object logic at the +moment of creating the instance of the class. Constructors have the same name +as the class. Constructors might have parameters, to initialize the data +members of the new object. + +For more information, see [about_Classes_Constructors][03]. + +## Hidden keyword + +The `hidden` keyword hides a class member. The member is still accessible to +the user and is available in all scopes in which the object is available. +Hidden members are hidden from the `Get-Member` cmdlet and can't be displayed +using tab completion or IntelliSense outside the class definition. + +The `hidden` keyword only applies to class members, not a class itself. + +Hidden class members are: + +- Not included in the default output for the class. +- Not included in the list of class members returned by the `Get-Member` + cmdlet. To show hidden members with `Get-Member`, use the **Force** + parameter. +- Not displayed in tab completion or IntelliSense unless the completion occurs + in the class that defines the hidden member. +- Public members of the class. They can be accessed, inherited, and modified. + Hiding a member doesn't make it private. It only hides the member as + described in the previous points. + +> [!NOTE] +> When you hide any overload for a method, that method is removed from +> IntelliSense, completion results, and the default output for `Get-Member`. +> When you hide any constructor, the `new()` option is removed from +> IntelliSense and completion results. + +For more information about the keyword, see [about_Hidden][04]. For more +information about hidden properties, see [about_Classes_Properties][05]. For +more information about hidden methods, see [about_Classes_Methods][06]. For +more information about hidden constructors, see +[about_Classes_Constructors][07]. + +## Static keyword + +The `static` keyword defines a property or a method that exists in the class +and needs no instance. + +A static property is always available, independent of class instantiation. A +static property is shared across all instances of the class. A static method is +available always. All static properties live for the entire session span. + +The `static` keyword only applies to class members, not a class itself. + +For more information about static properties, see +[about_Classes_Properties][08]. For more information about static methods, see +[about_Classes_Methods][09]. For more information about static constructors, +see [about_Classes_Constructors][10]. + +## Inheritance in PowerShell classes + +You can extend a class by creating a new class that derives from an existing +class. The derived class inherits the properties and methods of the base class. +You can add or override the base class members as required. + +PowerShell doesn't support multiple inheritance. Classes can't inherit directly +from more than one class. + +Classes can also inherit from interfaces, which define a contract. A class that +inherits from an interface must implement that contract. When it does, the +class can be used like any other class implementing that interface. + +For more information about deriving classes that inherit from a base class or +implement interfaces, see +[about_Classes_Inheritance][11]. + +## NoRunspaceAffinity attribute + +A runspace is the operating environment for the commands invoked by PowerShell. +This environment includes the commands and data that are currently present, and +any language restrictions that currently apply. + +By default, a PowerShell class is affiliated with the **Runspace** where it's +created. Using a PowerShell class in `ForEach-Object -Parallel` isn't safe. +Method invocations on the class are marshalled back to the **Runspace** where +it was created, which can corrupt the state of the **Runspace** or cause a +deadlock. + +Adding the `NoRunspaceAffinity` attribute to the class definition ensures that +the PowerShell class isn't affiliated with a particular runspace. Method +invocations, both instance and static, use the **Runspace** of the running +thread and the thread's current session state. + +The attribute was added in PowerShell 7.4. + +For an illustration of the difference in behavior for classes with and without +the `NoRunspaceAffinity` attribute, see +[Example 4](#example-4---class-definition-with-and-without-runspace-affinity). + +## Exporting classes with type accelerators + +By default, PowerShell modules don't automatically export classes and +enumerations defined in PowerShell. The custom types aren't available outside +of the module without calling a `using module` statement. + +However, if a module adds type accelerators, those type accelerators are +immediately available in the session after users import the module. + +> [!NOTE] +> Adding type accelerators to the session uses an internal (not public) API. +> Using this API may cause conflicts. The pattern described below throws an +> error if a type accelerator with the same name already exists when you import +> the module. It also removes the type accelerators when you remove the module +> from the session. +> +> This pattern ensures that the types are available in a session. It doesn't +> affect IntelliSense or completion when authoring a script file in VS Code. +> To get IntelliSense and completion suggestions for custom types in VS Code, +> you need to add a `using module` statement to the top of the script. + +The following pattern shows how you can register PowerShell classes and +enumerations as type accelerators in a module. Add the snippet to the root +script module after any type definitions. Make sure the `$ExportableTypes` +variable contains each of the types you want to make available to users when +they import the module. The other code doesn't require any editing. + +```powershell +# Define the types to export with type accelerators. +$ExportableTypes =@( + [DefinedTypeName] +) +# Get the internal TypeAccelerators class to use its static methods. +$TypeAcceleratorsClass = [psobject].Assembly.GetType( + 'System.Management.Automation.TypeAccelerators' +) +# Ensure none of the types would clobber an existing type accelerator. +# If a type accelerator with the same name exists, throw an exception. +$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get +foreach ($Type in $ExportableTypes) { + if ($Type.FullName -in $ExistingTypeAccelerators.Keys) { + $Message = @( + "Unable to register type accelerator '$($Type.FullName)'" + 'Accelerator already exists.' + ) -join ' - ' + + throw [System.Management.Automation.ErrorRecord]::new( + [System.InvalidOperationException]::new($Message), + 'TypeAcceleratorAlreadyExists', + [System.Management.Automation.ErrorCategory]::InvalidOperation, + $Type.FullName + ) + } +} +# Add type accelerators for every exportable type. +foreach ($Type in $ExportableTypes) { + $TypeAcceleratorsClass::Add($Type.FullName, $Type) +} +# Remove type accelerators when the module is removed. +$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { + foreach($Type in $ExportableTypes) { + $TypeAcceleratorsClass::Remove($Type.FullName) + } +}.GetNewClosure() +``` + +When users import the module, any types added to the type accelerators for the +session are immediately available for IntelliSense and completion. When the +module is removed, so are the type accelerators. + +## Manually importing classes from a PowerShell module + +`Import-Module` and the `#requires` statement only import the module functions, +aliases, and variables, as defined by the module. Classes aren't imported. + +If a module defines classes and enumerations but doesn't add type accelerators +for those types, use a `using module` statement to import them. + +The `using module` statement imports classes and enumerations from the root +module (`ModuleToProcess`) of a script module or binary module. It doesn't +consistently import classes defined in nested modules or classes defined in +scripts that are dot-sourced into the root module. Define classes that you want +to be available to users outside of the module directly in the root module. + +For more information about the `using` statement, see [about_Using][12]. + +## Loading newly changed code during development + +During development of a script module, it's common to make changes to the code +then load the new version of the module using `Import-Module` with the +**Force** parameter. Reloading the module only works for changes to functions +in the root module. `Import-Module` doesn't reload any nested modules. Also, +there's no way to load any updated classes. + +To ensure that you're running the latest version, you must start a new session. +Classes and enumerations defined in PowerShell and imported with a `using` +statement can't be unloaded. + +Another common development practice is to separate your code into different +files. If you have function in one file that use classes defined in another +module, you should use the `using module` statement to ensure that the +functions have the class definitions that are needed. + +## The PSReference type isn't supported with class members + +The `[ref]` type accelerator is shorthand for the **PSReference** class. Using +`[ref]` to type-cast a class member fails silently. APIs that use `[ref]` +parameters can't be used with class members. The **PSReference** class was +designed to support COM objects. COM objects have cases where you need to pass +a value in by reference. + +For more information, see [PSReference Class][13]. + +## Limitations + +The following lists include limitations for defining PowerShell classes and +workaround for those limitations, if any. + +### General limitations + +- Class members can't use **PSReference** as their type. + + Workaround: None. +- PowerShell classes can't be unloaded or reloaded in a session. + + Workaround: Start a new session. +- PowerShell classes defined in a module aren't automatically imported. + + Workaround: Add the defined types to the list of type accelerators in the + root module. This makes the types available on module import. +- The `hidden` and `static` keywords only apply to class members, not a class + definition. + + Workaround: None. +- By default, PowerShell classes aren't safe to use in parallel execution + across runspaces. When you Invoke methods on a class, PowerShell marshalls + the invocations back to the **Runspace** where the class was created, which + can corrupt the state of the **Runspace** or cause a deadlock. + + Workaround: Add the `NoRunspaceAffinity` attribute to the class declaration. + +### Constructor limitations + +- Constructor chaining isn't implemented. + + Workaround: Define hidden `Init()` methods and call them from within the + constructors. +- Constructor parameters can't use any attributes, including validation + attributes. + + Workaround: Reassign the parameters in the constructor body with the + validation attribute. +- Constructor parameters can't define default values. The parameters are + always mandatory. + + Workaround: None. +- If any overload of a constructor is hidden, every overload for the + constructor is treated as hidden too. + + Workaround: None. + +### Method limitations + +- Method parameters can't use any attributes, including validation + attributes. + + Workaround: Reassign the parameters in the method body with the validation + attribute or define the method in the static constructor with the + `Update-TypeData` cmdlet. +- Method parameters can't define default values. The parameters are always + mandatory. + + Workaround: Define the method in the static constructor with the + `Update-TypeData` cmdlet. +- Methods are always public, even when they're hidden. They can be overridden + when the class is inherited. + + Workaround: None. +- If any overload of a method is hidden, every overload for that method is + treated as hidden too. + + Workaround: None. + +### Property limitations + +- Static properties are always mutable. PowerShell classes can't define + immutable static properties. + + Workaround: None. +- Properties can't use the **ValidateScript** attribute, because class + property attribute arguments must be constants. + + Workaround: Define a class that inherits from the + **ValidateArgumentsAttribute** type and use that attribute instead. +- Directly declared properties can't define custom getter and setter + implementations. + + Workaround: Define a hidden property and use `Update-TypeData` to define the + visible getter and setter logic. +- Properties can't use the **Alias** attribute. The attribute only applies to + parameters, cmdlets, and functions. + + Workaround: Use the `Update-TypeData` cmdlet to define aliases in the class + constructors. +- When a PowerShell class is converted to JSON with the `ConvertTo-Json` + cmdlet, the output JSON includes all hidden properties and their values. + + Workaround: None + +### Inheritance limitations + +- PowerShell doesn't support defining interfaces in script code. + + Workaround: Define interfaces in C# and reference the assembly that defines + the interfaces. +- PowerShell classes can only inherit from one base class. + + Workaround: Class inheritance is transitive. A derived class can inherit + from another derived class to get the properties and methods of a base + class. +- When inheriting from a generic class or interface, the type parameter for + the generic must already be defined. A class can't define itself as the + type parameter for a class or interface. + + Workaround: To derive from a generic base class or interface, define the + custom type in a different `.psm1` file and use the `using module` + statement to load the type. There's no workaround for a custom type to use + itself as the type parameter when inheriting from a generic. + +## See also + +- [about_Classes_Constructors][03] +- [about_Classes_Inheritance][11] +- [about_Classes_Methods][02] +- [about_Classes_Properties][01] +- [about_Enum][14] +- [about_Hidden][04] +- [about_Language_Keywords][15] +- [about_Methods][16] +- [about_Using][12] + + +[01]: about_Classes_Properties.md +[02]: about_Classes_Methods.md +[03]: about_Classes_Constructors.md +[04]: about_Hidden.md +[05]: about_Classes_Properties.md#hidden-properties +[06]: about_Classes_Methods.md#hidden-methods +[07]: about_Classes_Constructors.md#hidden-constructors +[08]: about_Classes_Properties.md#static-properties +[09]: about_Classes_Methods.md#static-methods +[10]: about_Classes_Constructors.md#static-constructors +[11]: about_Classes_Inheritance.md +[12]: about_Using.md +[13]: /dotnet/api/system.management.automation.psreference +[14]: about_Enum.md +[15]: about_language_keywords.md +[16]: about_methods.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Constructors.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Constructors.md new file mode 100644 index 000000000000..49a196ded751 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Constructors.md @@ -0,0 +1,554 @@ +--- +description: Describes how to define constructors for PowerShell classes. +Locale: en-US +ms.date: 11/13/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_constructors?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Classes_Constructors +--- + +# about_Classes_Constructors + +## Short description + +Describes how to define constructors for PowerShell classes. + +## Long description + +Constructors enable you to set default values and validate object logic at the +moment of creating the instance of the class. Constructors have the same name +as the class. Constructors might have parameters, to initialize the data +members of the new object. + +PowerShell class constructors are defined as special methods on the class. They +behave the same as PowerShell class methods with the following exceptions: + +- Constructors don't have an output type. They can't use the `return` keyword. +- Constructors always have the same name as the class. +- Constructors can't be called directly. They only run when an instance is + created. +- Constructors never appear in the output for the `Get-Member` cmdlet. + +For more information about PowerShell class methods, see +[about_Classes_Methods][01]. + +The class can have zero or more constructors defined. If no constructor is +defined, the class is given a default parameterless constructor. This +constructor initializes all members to their default values. Object types and +strings are given null values. When you define constructor, no default +parameterless constructor is created. Create a parameterless constructor if one +is needed. + +You can also define a parameterless [static constructor][02]. + +## Syntax + +Class constructors use the following syntaxes: + +### Default constructor syntax + +```Syntax + () [: base([])] { + +} +``` + +### Static constructor syntax + +```Syntax +static () [: base([])] { + +} +``` + +### Parameterized constructor syntax (one-line) + +```Syntax + ([[]$[, []$...]]) [: base([])] { + +} +``` + +### Parameterized constructor syntax (multiline) + +```Syntax + ( + []$[, + []$...] +) [: base([])] { + +} +``` + +## Examples + +### Example 1 - Defining a class with the default constructor + +The **ExampleBook1** class doesn't define a constructor. Instead, it uses the +automatic default constructor. + +```powershell +class ExampleBook1 { + [string] $Name + [string] $Author + [int] $Pages + [datetime] $PublishedOn +} + +[ExampleBook1]::new() +``` + +```Output +Name Author Pages PublishedOn +---- ------ ----- ----------- + 0 1/1/0001 12:00:00 AM +``` + +> [!NOTE] +> The default value for the **Name** and **Author** properties is `$null` +> because they're typed as strings, which is a reference type. The other +> properties have the default value for their defined type, because they're +> value type properties. For more information on the default values for +> properties, see ["Default property values" in about_Classes_Properties][03]. + +### Example 2 - Overriding the default constructor + +**ExampleBook2** explicitly defines the default constructor, setting the values +for **PublishedOn** to the current date and **Pages** to `1`. + +```powershell +class ExampleBook2 { + [string] $Name + [string] $Author + [int] $Pages + [datetime] $PublishedOn + + ExampleBook2() { + $this.PublishedOn = (Get-Date).Date + $this.Pages = 1 + } +} + +[ExampleBook2]::new() +``` + +```Output +Name Author Pages PublishedOn +---- ------ ----- ----------- + 1 11/1/2023 12:00:00 AM +``` + +### Example 3 - Defining constructor overloads + +The **ExampleBook3** class defines three constructor overloads, enabling users +to create an instance of the class from a hashtable, by passing every property +value, and by passing the name of the book and author. The class doesn't define +the default constructor. + +```powershell +class ExampleBook3 { + [string] $Name + [string] $Author + [int] $Pages + [datetime] $PublishedOn + + ExampleBook3([hashtable]$Info) { + switch ($Info.Keys) { + 'Name' { $this.Name = $Info.Name } + 'Author' { $this.Author = $Info.Author } + 'Pages' { $this.Pages = $Info.Pages } + 'PublishedOn' { $this.PublishedOn = $Info.PublishedOn } + } + } + + ExampleBook3( + [string] $Name, + [string] $Author, + [int] $Pages, + [datetime] $PublishedOn + ) { + $this.Name = $Name + $this.Author = $Author + $this.Pages = $Pages + $this.PublishedOn = $PublishedOn + } + + ExampleBook3([string]$Name, [string]$Author) { + $this.Name = $Name + $this.Author = $Author + } +} + +[ExampleBook3]::new(@{ + Name = 'The Hobbit' + Author = 'J.R.R. Tolkien' + Pages = 310 + PublishedOn = '1937-09-21' +}) +[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien', 310, '1937-09-21') +[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien') +[ExampleBook3]::new() +``` + +```Output +Name Author Pages PublishedOn +---- ------ ----- ----------- +The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM +The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM +The Hobbit J.R.R. Tolkien 0 1/1/0001 12:00:00 AM + +MethodException: +Line | + 42 | [ExampleBook3]::new() + | ~~~~~~~~~~~~~~~~~~~~~ + | Cannot find an overload for "new" and the argument count: "0". +``` + +Calling the default constructor returns a method exception. The automatic +default constructor is only defined for a class when the class doesn't define +any constructors. Because **ExampleBook3** defines multiple overloads, the +default constructor isn't automatically added to the class. + +### Example 4 - Chaining constructors with a shared method + +This example shows how you can write reusable shared code for constructors. +PowerShell classes can't use constructor chaining, so this example class +defines an `Init()` method instead. The method has several overloads. The +overloads with fewer parameters call the more explicit overloads with default +values for the unspecified parameters. + +```powershell +class ExampleBook4 { + [string] $Name + [string] $Author + [datetime] $PublishedOn + [int] $Pages + + ExampleBook4() { + $this.Init() + } + ExampleBook4([string]$Name) { + $this.Init($Name) + } + ExampleBook4([string]$Name, [string]$Author) { + $this.Init($Name, $Author) + } + ExampleBook4([string]$Name, [string]$Author, [datetime]$PublishedOn) { + $this.Init($Name, $Author, $PublishedOn) + } + ExampleBook4( + [string]$Name, + [string]$Author, + [datetime]$PublishedOn, + [int]$Pages + ) { + $this.Init($Name, $Author, $PublishedOn, $Pages) + } + + hidden Init() { + $this.Init('Unknown') + } + hidden Init([string]$Name) { + $this.Init($Name, 'Unknown') + } + hidden Init([string]$Name, [string]$Author) { + $this.Init($Name, $Author, (Get-Date).Date) + } + hidden Init([string]$Name, [string]$Author, [datetime]$PublishedOn) { + $this.Init($Name, $Author, $PublishedOn, 1) + } + hidden Init( + [string]$Name, + [string]$Author, + [datetime]$PublishedOn, + [int]$Pages + ) { + $this.Name = $Name + $this.Author = $Author + $this.PublishedOn = $PublishedOn + $this.Pages = $Pages + } +} + +[ExampleBook4]::new() +[ExampleBook4]::new('The Hobbit') +[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien') +[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien', (Get-Date '1937-9-21')) +[ExampleBook4]::new( + 'The Hobbit', + 'J.R.R. Tolkien', + (Get-Date '1937-9-21'), + 310 +) +``` + +```Output +Name Author PublishedOn Pages +---- ------ ----------- ----- +Unknown Unknown 11/1/2023 12:00:00 AM 1 +The Hobbit Unknown 11/1/2023 12:00:00 AM 1 +The Hobbit J.R.R. Tolkien 11/1/2023 12:00:00 AM 1 +The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 1 +The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 310 +``` + +### Example 5 - Derived class constructors + +The following examples use classes that define the static, default, and +parameterized constructors for a base class and a derived class that inherits +from the base class. + +```powershell +class BaseExample { + static [void] DefaultMessage([type]$Type) { + Write-Verbose "[$($Type.Name)] default constructor" + } + + static [void] StaticMessage([type]$Type) { + Write-Verbose "[$($Type.Name)] static constructor" + } + + static [void] ParamMessage([type]$Type, [object]$Value) { + Write-Verbose "[$($Type.Name)] param constructor ($Value)" + } + + static BaseExample() { [BaseExample]::StaticMessage([BaseExample]) } + BaseExample() { [BaseExample]::DefaultMessage([BaseExample]) } + BaseExample($Value) { [BaseExample]::ParamMessage([BaseExample], $Value) } +} + +class DerivedExample : BaseExample { + static DerivedExample() { [BaseExample]::StaticMessage([DerivedExample]) } + DerivedExample() { [BaseExample]::DefaultMessage([DerivedExample]) } + + DerivedExample([int]$Number) : base($Number) { + [BaseExample]::ParamMessage([DerivedExample], $Number) + } + DerivedExample([string]$String) { + [BaseExample]::ParamMessage([DerivedExample], $String) + } +} +``` + +The following block shows the verbose messaging for calling the base class +constructors. The static constructor message is only emitted the first time an +instance of the class is created. + +```powershell +PS> $VerbosePreference = 'Continue' +PS> $b = [BaseExample]::new() + +VERBOSE: [BaseExample] static constructor +VERBOSE: [BaseExample] default constructor + +PS> $b = [BaseExample]::new() + +VERBOSE: [BaseExample] default constructor + +PS> $b = [BaseExample]::new(1) + +VERBOSE: [BaseExample] param constructor (1) +``` + +The next block shows the verbose messaging for calling the derived class +constructors in a new session. The first time a derived class constructor is +called, the static constructors for the base class and derived class are +called. Those constructors aren't called again in the session. The constructors +for the base class always run before the constructors for the derived class. + +```powershell +PS> $VerbosePreference = 'Continue' +PS> $c = [DerivedExample]::new() + +VERBOSE: [BaseExample] static constructor +VERBOSE: [DerivedExample] static constructor +VERBOSE: [BaseExample] default constructor +VERBOSE: [DerivedExample] default constructor + +PS> $c = [DerivedExample]::new() + +VERBOSE: [BaseExample] default constructor +VERBOSE: [DerivedExample] default constructor + +PS> $c = [DerivedExample]::new(1) + +VERBOSE: [BaseExample] param constructor (1) +VERBOSE: [DerivedExample] param constructor (1) + +PS> $c = [DerivedExample]::new('foo') + +VERBOSE: [BaseExample] default constructor +VERBOSE: [DerivedExample] param constructor (foo) +``` + +## Constructor run ordering + +When a class instantiates, the code for one or more constructors executes. + +For classes that don't inherit from another class, the ordering is: + +1. The static constructor for the class. +1. The applicable constructor overload for the class. + +For derived classes that inherit from another class, the ordering is: + +1. The static constructor for the base class. +1. The static constructor for the derived class. +1. If the derived class constructor explicitly calls a base constructor + overload, it runs that constructor for the base class. If it doesn't + explicitly call a base constructor, it runs the default constructor for the + base class. +1. The applicable constructor overload for the derived class. + +In all cases, static constructors only run once in a session. + +For an example of constructor behavior and ordering, see [Example 5][06]. + +## Hidden constructors + +You can hide constructors of a class by declaring them with the `hidden` +keyword. Hidden class constructors are: + +- Not included in the default output for the class. +- Not included in the list of class members returned by the `Get-Member` + cmdlet. To show hidden properties with `Get-Member`, use the **Force** + parameter. +- Not displayed in tab completion or IntelliSense unless the completion occurs + in the class that defines the hidden property. +- Public members of the class. They can be accessed and modified. Hiding a + property doesn't make it private. It only hides the property as described in + the previous points. + +> [!NOTE] +> When you hide any constructor, the `new()` option is removed from +> IntelliSense and completion results. + +For more information about the `hidden` keyword, see [about_Hidden][04]. + +## Static constructors + +You can define a constructor as belonging to the class itself instead of +instances of the class by declaring the constructor with the `static` keyword. +Static class constructors: + +- Only invoke the first time an instance of the class is created in the + session. +- Can't have any parameters. +- Can't access instance properties or methods with the `$this` variable. + +## Constructors for derived classes + +When a class inherits from another class, constructors can invoke a constructor +from the base class with the `base` keyword. If the derived class doesn't +explicitly invoke a constructor from the base class, it invokes the default +constructor for the base class instead. + +To invoke a nondefault base constructor, add `: base()` after the +constructor parameters and before the body block. + +```Syntax +class : { + () : () { + # initialization code + } +} +``` + +When defining a constructor that calls a base class constructor, the parameters +can be any of the following items: + +- The variable of any parameter on the derived class constructor. +- Any static value. +- Any expression that evaluates to a value of the parameter type. + +For an example of constructors on a derived class, see [Example 5][06]. + +## Chaining constructors + +Unlike C#, PowerShell class constructors can't use chaining with the +`: this()` syntax. To reduce code duplication, use a hidden +`Init()` method with multiple overloads to the same effect. [Example 4][05] +shows a class using this pattern. + +## Adding instance properties and methods with Update-TypeData + +Beyond declaring properties and methods directly in the class definition, you +can define properties for instances of a class in the static constructor using +the `Update-TypeData` cmdlet. + +Use this snippet as a starting point for the pattern. Replace the placeholder +text in angle brackets as needed. + +```powershell +class { + static [hashtable[]] $MemberDefinitions = @( + @{ + Name = '' + MemberType = '' + Value = + } + ) + + static () { + $TypeName = [].Name + foreach ($Definition in []::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } +} +``` + +> [!TIP] +> The `Add-Member` cmdlet can add properties and methods to a class in +> non-static constructors, but the cmdlet is run every time the constructor +> is called. Using `Update-TypeData` in the static constructor ensures that the +> code for adding the members to the class only needs to run once in a session. +> +> Only add properties to the class in non-static constructors when they can't +> be defined with `Update-TypeData`, like read-only properties. + +For more information about defining instance methods with `Update-TypeData`, +see [about_Classes_Methods][07]. For more information about defining instance +properties with `Update-TypeData`, see [about_Classes_Properties][08]. + +## Limitations + +PowerShell class constructors have the following limitations: + +- Constructor chaining isn't implemented. + + Workaround: Define hidden `Init()` methods and call them from within the + constructors. +- Constructor parameters can't use any attributes, including validation + attributes. + + Workaround: Reassign the parameters in the constructor body with the + validation attribute. +- Constructor parameters can't define default values. The parameters are always + mandatory. + + Workaround: None. +- If any overload of a constructor is hidden, every overload for the + constructor is treated as hidden too. + + Workaround: None. + +## See also + +- [about_Classes][10] +- [about_Classes_Inheritance][11] +- [about_Classes_Methods][01] +- [about_Classes_Properties][09] + + +[01]: about_Classes_Methods.md +[02]: #static-constructors +[03]: about_Classes_Properties.md#default-property-values +[04]: about_Hidden.md +[05]: #example-4---chaining-constructors-with-a-shared-method +[06]: #example-5---derived-class-constructors +[07]: about_Classes_Methods.md#defining-instance-methods-with-update-typedata +[08]: about_Classes_Properties.md#defining-instance-properties-with-update-typedata +[09]: about_Classes_Properties.md +[10]: about_Classes.md +[11]: about_Classes_Inheritance.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Inheritance.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Inheritance.md new file mode 100644 index 000000000000..7a0f8117c5d6 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Inheritance.md @@ -0,0 +1,1610 @@ +--- +description: Describes how you can define classes that extend other types. +Locale: en-US +ms.date: 11/10/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_inheritance?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Classes_Inheritance +--- + +# about_Classes_Inheritance + +## Short description + +Describes how you can define classes that extend other types. + +## Long description + +PowerShell classes support _inheritance_, which allows you to define a child +class that reuses (inherits), extends, or modifies the behavior of a parent +class. The class whose members are inherited is called the _base class_. The +class that inherits the members of the base class is called the _derived +class_. + +PowerShell supports single inheritance only. A class can only inherit from a +single class. However, inheritance is transitive, which allows you to define an +inheritance hierarchy for a set of types. In other words, type **D** can +inherit from type **C**, which inherits from type **B**, which inherits from +the base class type **A**. Because inheritance is transitive, the members of +type **A** are available to type **D**. + +Derived classes don't inherit all members of the base class. The following +members aren't inherited: + +- Static constructors, which initialize the static data of a class. +- Instance constructors, which you call to create a new instance of the class. + Each class must define its own constructors. + +You can extend a class by creating a new class that derives from an existing +class. The derived class inherits the properties and methods of the base class. +You can add or override the base class members as required. + +Classes can also inherit from interfaces, which define a contract. A class that +inherits from an interface must implement that contract. When it does, the +class is usable like any other class implementing that interface. If a class +inherits from an interface but doesn't implement the interface, PowerShell +raises a parsing error for the class. + +Some PowerShell operators depend on a class implementing a specific interface. +For example, the `-eq` operator only checks for reference equality unless the +class implements the **System.IEquatable** interface. The `-le`, `-lt`, `-ge`, +and `-gt` operators only work on classes that implement the +**System.IComparable** interface. + +A derived class uses the `:` syntax to extend a base class or implement +interfaces. The derived class should always be leftmost in the class +declaration. + +This example shows the basic PowerShell class inheritance syntax. + +```powershell +Class Derived : Base {...} +``` + +This example shows inheritance with an interface declaration coming after the +base class. + +```powershell +Class Derived : Base, Interface {...} +``` + +## Syntax + +Class inheritance uses the following syntaxes: + +### One line syntax + +```Syntax +class : [, ...] { + +} +``` + +For example: + +```powershell +# Base class only +class Derived : Base {...} +# Interface only +class Derived : System.IComparable {...} +# Base class and interface +class Derived : Base, System.IComparable {...} +``` + +### Multiline syntax + +```Syntax +class : [, + ...] { + +} +``` + +For example: + +```powershell +class Derived : Base, + System.IComparable, + System.IFormattable, + System.IConvertible { + # Derived class definition +} +``` + +## Examples + +### Example 1 - Inheriting and overriding from a base class + +The following example shows the behavior of inherited properties with and +without overriding. Run the code blocks in order after reading their +description. + +#### Defining the base class + +The first code block defines **PublishedWork** as a base class. It has two +static properties, **List** and **Artists**. Next, it defines the static +`RegisterWork()` method to add works to the static **List** property and the +artists to the **Artists** property, writing a message for each new entry in +the lists. + +The class defines three instance properties that describe a published work. +Finally, it defines the `Register()` and `ToString()` instance methods. + +```powershell +class PublishedWork { + static [PublishedWork[]] $List = @() + static [string[]] $Artists = @() + + static [void] RegisterWork([PublishedWork]$Work) { + $wName = $Work.Name + $wArtist = $Work.Artist + if ($Work -notin [PublishedWork]::List) { + Write-Verbose "Adding work '$wName' to works list" + [PublishedWork]::List += $Work + } else { + Write-Verbose "Work '$wName' already registered." + } + if ($wArtist -notin [PublishedWork]::Artists) { + Write-Verbose "Adding artist '$wArtist' to artists list" + [PublishedWork]::Artists += $wArtist + } else { + Write-Verbose "Artist '$wArtist' already registered." + } + } + + static [void] ClearRegistry() { + Write-Verbose "Clearing PublishedWork registry" + [PublishedWork]::List = @() + [PublishedWork]::Artists = @() + } + + [string] $Name + [string] $Artist + [string] $Category + + [void] Init([string]$WorkType) { + if ([string]::IsNullOrEmpty($this.Category)) { + $this.Category = "${WorkType}s" + } + } + + PublishedWork() { + $WorkType = $this.GetType().FullName + $this.Init($WorkType) + Write-Verbose "Defined a published work of type [$WorkType]" + } + + PublishedWork([string]$Name, [string]$Artist) { + $WorkType = $this.GetType().FullName + $this.Name = $Name + $this.Artist = $Artist + $this.Init($WorkType) + + Write-Verbose "Defined '$Name' by $Artist as a published work of type [$WorkType]" + } + + PublishedWork([string]$Name, [string]$Artist, [string]$Category) { + $WorkType = $this.GetType().FullName + $this.Name = $Name + $this.Artist = $Artist + $this.Init($WorkType) + + Write-Verbose "Defined '$Name' by $Artist ($Category) as a published work of type [$WorkType]" + } + + [void] Register() { [PublishedWork]::RegisterWork($this) } + [string] ToString() { return "$($this.Name) by $($this.Artist)" } +} +``` + +#### Defining a derived class without overrides + +The first derived class is **Album**. It doesn't override any properties or +methods. It adds a new instance property, **Genres**, that doesn't exist on the +base class. + +```powershell +class Album : PublishedWork { + [string[]] $Genres = @() +} +``` + +The following code block shows the behavior of the derived **Album** class. +First, it sets the `$VerbosePreference` so that the messages from the class +methods emit to the console. It creates three instances of the class, shows +them in a table, and then registers them with the inherited static +`RegisterWork()` method. It then calls the same static method on the base class +directly. + +```powershell +$VerbosePreference = 'Continue' +$Albums = @( + [Album]@{ + Name = 'The Dark Side of the Moon' + Artist = 'Pink Floyd' + Genres = 'Progressive rock', 'Psychedelic rock' + } + [Album]@{ + Name = 'The Wall' + Artist = 'Pink Floyd' + Genres = 'Progressive rock', 'Art rock' + } + [Album]@{ + Name = '36 Chambers' + Artist = 'Wu-Tang Clan' + Genres = 'Hip hop' + } +) + +$Albums | Format-Table +$Albums | ForEach-Object { [Album]::RegisterWork($_) } +$Albums | ForEach-Object { [PublishedWork]::RegisterWork($_) } +``` + +```Output +VERBOSE: Defined a published work of type [Album] +VERBOSE: Defined a published work of type [Album] +VERBOSE: Defined a published work of type [Album] + +Genres Name Artist Category +------ ---- ------ -------- +{Progressive rock, Psychedelic rock} The Dark Side of the Moon Pink Floyd Albums +{Progressive rock, Art rock} The Wall Pink Floyd Albums +{Hip hop} 36 Chambers Wu-Tang Clan Albums + +VERBOSE: Adding work 'The Dark Side of the Moon' to works list +VERBOSE: Adding artist 'Pink Floyd' to artists list +VERBOSE: Adding work 'The Wall' to works list +VERBOSE: Artist 'Pink Floyd' already registered. +VERBOSE: Adding work '36 Chambers' to works list +VERBOSE: Adding artist 'Wu-Tang Clan' to artists list + +VERBOSE: Work 'The Dark Side of the Moon' already registered. +VERBOSE: Artist 'Pink Floyd' already registered. +VERBOSE: Work 'The Wall' already registered. +VERBOSE: Artist 'Pink Floyd' already registered. +VERBOSE: Work '36 Chambers' already registered. +VERBOSE: Artist 'Wu-Tang Clan' already registered. +``` + +Notice that even though the **Album** class didn't define a value for +**Category** or any constructors, the property was defined by the default +constructor of the base class. + +In the verbose messaging, the second call to the `RegisterWork()` method +reports that the works and artists are already registered. Even though the +first call to `RegisterWork()` was for the derived **Album** class, it used the +inherited static method from the base **PublishedWork** class. That method +updated the static **List** and **Artist** properties on the base class, which +the derived class didn't override. + +The next code block clears the registry and calls the `Register()` instance +method on the **Album** objects. + +```powershell +[PublishedWork]::ClearRegistry() +$Albums.Register() +``` + +```Output +VERBOSE: Clearing PublishedWork registry + +VERBOSE: Adding work 'The Dark Side of the Moon' to works list +VERBOSE: Adding artist 'Pink Floyd' to artists list +VERBOSE: Adding work 'The Wall' to works list +VERBOSE: Artist 'Pink Floyd' already registered. +VERBOSE: Adding work '36 Chambers' to works list +VERBOSE: Adding artist 'Wu-Tang Clan' to artists list +``` + +The instance method on the **Album** objects has the same effect as calling the +static method on the derived or base class. + +The following code block compares the static properties for the base class and +the derived class, showing that they're the same. + +```powershell +[pscustomobject]@{ + '[PublishedWork]::List' = [PublishedWork]::List -join ",`n" + '[Album]::List' = [Album]::List -join ",`n" + '[PublishedWork]::Artists' = [PublishedWork]::Artists -join ",`n" + '[Album]::Artists' = [Album]::Artists -join ",`n" + 'IsSame::List' = ( + [PublishedWork]::List.Count -eq [Album]::List.Count -and + [PublishedWork]::List.ToString() -eq [Album]::List.ToString() + ) + 'IsSame::Artists' = ( + [PublishedWork]::Artists.Count -eq [Album]::Artists.Count -and + [PublishedWork]::Artists.ToString() -eq [Album]::Artists.ToString() + ) +} | Format-List +``` + +```Output +[PublishedWork]::List : The Dark Side of the Moon by Pink Floyd, + The Wall by Pink Floyd, + 36 Chambers by Wu-Tang Clan +[Album]::List : The Dark Side of the Moon by Pink Floyd, + The Wall by Pink Floyd, + 36 Chambers by Wu-Tang Clan +[PublishedWork]::Artists : Pink Floyd, + Wu-Tang Clan +[Album]::Artists : Pink Floyd, + Wu-Tang Clan +IsSame::List : True +IsSame::Artists : True +``` + +#### Defining a derived class with overrides + +The next code block defines the **Illustration** class inheriting from the base +**PublishedWork** class. The new class extends the base class by defining the +**Medium** instance property with a default value of `Unknown`. + +Unlike the derived **Album** class, **Illustration** overrides the following +properties and methods: + +- It overrides the static **Artists** property. The definition is the same, but + the **Illustration** class declares it directly. +- It overrides the **Category** instance property, setting the default value to + `Illustrations`. +- It overrides the `ToString()` instance method so the string representation of + an illustration includes the medium it was created with. + +The class also defines the static `RegisterIllustration()` method to first call +the base class `RegisterWork()` method and then add the artist to the +overridden **Artists** static property on the derived class. + +Finally, the class overrides all three constructors: + +1. The default constructor is empty except for a verbose message indicating it + created an illustration. +1. The next constructor takes two string values for the name and artist that + created the illustration. Instead of implementing the logic for setting the + **Name** and **Artist** properties, the constructor calls the appropriate + constructor from the base class. +1. The last constructor takes three string values for the name, artist, and + medium of the illustration. Both constructors write a verbose message + indicating that they created an illustration. + +```powershell +class Illustration : PublishedWork { + static [string[]] $Artists = @() + + static [void] RegisterIllustration([Illustration]$Work) { + $wArtist = $Work.Artist + + [PublishedWork]::RegisterWork($Work) + + if ($wArtist -notin [Illustration]::Artists) { + Write-Verbose "Adding illustrator '$wArtist' to artists list" + [Illustration]::Artists += $wArtist + } else { + Write-Verbose "Illustrator '$wArtist' already registered." + } + } + + [string] $Category = 'Illustrations' + [string] $Medium = 'Unknown' + + [string] ToString() { + return "$($this.Name) by $($this.Artist) ($($this.Medium))" + } + + Illustration() { + Write-Verbose 'Defined an illustration' + } + + Illustration([string]$Name, [string]$Artist) : base($Name, $Artist) { + Write-Verbose "Defined '$Name' by $Artist ($($this.Medium)) as an illustration" + } + + Illustration([string]$Name, [string]$Artist, [string]$Medium) { + $this.Name = $Name + $this.Artist = $Artist + $this.Medium = $Medium + + Write-Verbose "Defined '$Name' by $Artist ($Medium) as an illustration" + } +} +``` + +The following code block shows the behavior of the derived **Illustration** +class. It creates three instances of the class, shows them in a table, and then +registers them with the inherited static `RegisterWork()` method. It then calls +the same static method on the base class directly. Finally, it writes messages +showing the list of registered artists for the base class and the derived +class. + +```powershell +$Illustrations = @( + [Illustration]@{ + Name = 'The Funny Thing' + Artist = 'Wanda Gág' + Medium = 'Lithography' + } + [Illustration]::new('Millions of Cats', 'Wanda Gág') + [Illustration]::new( + 'The Lion and the Mouse', + 'Jerry Pinkney', + 'Watercolor' + ) +) + +$Illustrations | Format-Table +$Illustrations | ForEach-Object { [Illustration]::RegisterIllustration($_) } +$Illustrations | ForEach-Object { [PublishedWork]::RegisterWork($_) } +"Published work artists: $([PublishedWork]::Artists -join ', ')" +"Illustration artists: $([Illustration]::Artists -join ', ')" +``` + +```Output +VERBOSE: Defined a published work of type [Illustration] +VERBOSE: Defined an illustration +VERBOSE: Defined 'Millions of Cats' by Wanda Gág as a published work of type [Illustration] +VERBOSE: Defined 'Millions of Cats' by Wanda Gág (Unknown) as an illustration +VERBOSE: Defined a published work of type [Illustration] +VERBOSE: Defined 'The Lion and the Mouse' by Jerry Pinkney (Watercolor) as an illustration + +Category Medium Name Artist +-------- ------ ---- ------ +Illustrations Lithography The Funny Thing Wanda Gág +Illustrations Unknown Millions of Cats Wanda Gág +Illustrations Watercolor The Lion and the Mouse Jerry Pinkney + +VERBOSE: Adding work 'The Funny Thing' to works list +VERBOSE: Adding artist 'Wanda Gág' to artists list +VERBOSE: Adding illustrator 'Wanda Gág' to artists list +VERBOSE: Adding work 'Millions of Cats' to works list +VERBOSE: Artist 'Wanda Gág' already registered. +VERBOSE: Illustrator 'Wanda Gág' already registered. +VERBOSE: Adding work 'The Lion and the Mouse' to works list +VERBOSE: Adding artist 'Jerry Pinkney' to artists list +VERBOSE: Adding illustrator 'Jerry Pinkney' to artists list + +VERBOSE: Work 'The Funny Thing' already registered. +VERBOSE: Artist 'Wanda Gág' already registered. +VERBOSE: Work 'Millions of Cats' already registered. +VERBOSE: Artist 'Wanda Gág' already registered. +VERBOSE: Work 'The Lion and the Mouse' already registered. +VERBOSE: Artist 'Jerry Pinkney' already registered. + +Published work artists: Pink Floyd, Wu-Tang Clan, Wanda Gág, Jerry Pinkney + +Illustration artists: Wanda Gág, Jerry Pinkney +``` + +The verbose messaging from creating the instances shows that: + +- When creating the first instance, the base class default constructor was + called before the derived class default constructor. +- When creating the second instance, the explicitly inherited constructor was + called for the base class before the derived class constructor. +- When creating the third instance, the base class default constructor was + called before the derived class constructor. + +The verbose messages from the `RegisterWork()` method indicate that the works +and artists were already registered. This is because the +`RegisterIllustration()` method called the `RegisterWork()` method internally. + +However, when comparing the value of the static **Artist** property for both +the base class and derived class, the values are different. The **Artists** +property for the derived class only includes illustrators, not the album +artists. Redefining the **Artist** property in the derived class prevents the +class from returning the static property on the base class. + +The final code block calls the `ToString()` method on the entries of the +static **List** property on the base class. + +```powershell +[PublishedWork]::List | ForEach-Object -Process { $_.ToString() } +``` + +```Output +The Dark Side of the Moon by Pink Floyd +The Wall by Pink Floyd +36 Chambers by Wu-Tang Clan +The Funny Thing by Wanda Gág (Lithography) +Millions of Cats by Wanda Gág (Unknown) +The Lion and the Mouse by Jerry Pinkney (Watercolor) +``` + +The **Album** instances only return the name and artist in their string. The +**Illustration** instances also included the medium in parentheses, because +that class overrode the `ToString()` method. + +### Example 2 - Implementing interfaces + +The following example shows how a class can implement one or more interfaces. +The example extends the definition of a **Temperature** class to support more +operations and behaviors. + +#### Initial class definition + +Before implementing any interfaces, the **Temperature** class is defined with +two properties, **Degrees** and **Scale**. It defines constructors and three +instance methods for returning the instance as degrees of a particular scale. + +The class defines the available scales with the **TemperatureScale** +enumeration. + +```powershell +class Temperature { + [float] $Degrees + [TemperatureScale] $Scale + + Temperature() {} + Temperature([float] $Degrees) { $this.Degrees = $Degrees } + Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale } + Temperature([float] $Degrees, [TemperatureScale] $Scale) { + $this.Degrees = $Degrees + $this.Scale = $Scale + } + + [float] ToKelvin() { + switch ($this.Scale) { + Celsius { return $this.Degrees + 273.15 } + Fahrenheit { return ($this.Degrees + 459.67) * 5/9 } + } + return $this.Degrees + } + [float] ToCelsius() { + switch ($this.Scale) { + Fahrenheit { return ($this.Degrees - 32) * 5/9 } + Kelvin { return $this.Degrees - 273.15 } + } + return $this.Degrees + } + [float] ToFahrenheit() { + switch ($this.Scale) { + Celsius { return $this.Degrees * 9/5 + 32 } + Kelvin { return $this.Degrees * 9/5 - 459.67 } + } + return $this.Degrees + } +} + +enum TemperatureScale { + Celsius = 0 + Fahrenheit = 1 + Kelvin = 2 +} +``` + +However, in this basic implementation, there's a few limitations as shown in +the following example output: + +```powershell +$Celsius = [Temperature]::new() +$Fahrenheit = [Temperature]::new([TemperatureScale]::Fahrenheit) +$Kelvin = [Temperature]::new(0, 'Kelvin') + +$Celsius, $Fahrenheit, $Kelvin + +"The temperatures are: $Celsius, $Fahrenheit, $Kelvin" + +[Temperature]::new() -eq $Celsius + +$Celsius -gt $Kelvin +``` + +```Output +Degrees Scale +------- ----- + 0.00 Celsius + 0.00 Fahrenheit + 0.00 Kelvin + +The temperatures are: Temperature, Temperature, Temperature + +False + +InvalidOperation: +Line | + 11 | $Celsius -gt $Kelvin + | ~~~~~~~~~~~~~~~~~~~~ + | Cannot compare "Temperature" because it is not IComparable. +``` + +The output shows that instances of **Temperature**: + +- Don't display correctly as strings. +- Can't be checked properly for equivalency. +- Can't be compared. + +These three problems can be addressed by implementing interfaces for the class. + +#### Implementing IFormattable + +The first interface to implement for the **Temperature** class is +**System.IFormattable**. This interface enables formatting an instance of the +class as different strings. To implement the interface, the class needs to +inherit from **System.IFormattable** and define the `ToString()` instance +method. + +The `ToString()` instance method needs to have the following signature: + +```powershell +[string] ToString( + [string]$Format, + [System.IFormatProvider]$FormatProvider +) { + # Implementation +} +``` + +The signature that the interface requires is listed in the +[reference documentation][01]. + +For **Temperature**, the class should support three formats: `C` to return the +instance in Celsius, `F` to return it in Fahrenheit, and `K` to return it in +Kelvin. For any other format, the method should throw a +**System.FormatException**. + +```powershell +[string] ToString( + [string]$Format, + [System.IFormatProvider]$FormatProvider +) { + # If format isn't specified, use the defined scale. + if ([string]::IsNullOrEmpty($Format)) { + $Format = switch ($this.Scale) { + Celsius { 'C' } + Fahrenheit { 'F' } + Kelvin { 'K' } + } + } + # If format provider isn't specified, use the current culture. + if ($null -eq $FormatProvider) { + $FormatProvider = [CultureInfo]::CurrentCulture + } + # Format the temperature. + switch ($Format) { + 'C' { + return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C' + } + 'F' { + return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F' + } + 'K' { + return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K' + } + } + # If we get here, the format is invalid. + throw [System.FormatException]::new( + "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'" + ) +} +``` + +In this implementation, the method defaults to the instance scale for +format and the current culture when formatting the numerical degree value +itself. It uses the `To()` instance methods to convert the degrees, +formats them to two-decimal places, and appends the appropriate degree symbol +to the string. + +With the required signature implemented, the class can also define overloads to +make it easier to return the formatted instance. + +```powershell +[string] ToString([string]$Format) { + return $this.ToString($Format, $null) +} + +[string] ToString() { + return $this.ToString($null, $null) +} +``` + +The following code shows the updated definition for **Temperature**: + +```powershell +class Temperature : System.IFormattable { + [float] $Degrees + [TemperatureScale] $Scale + + Temperature() {} + Temperature([float] $Degrees) { $this.Degrees = $Degrees } + Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale } + Temperature([float] $Degrees, [TemperatureScale] $Scale) { + $this.Degrees = $Degrees + $this.Scale = $Scale + } + + [float] ToKelvin() { + switch ($this.Scale) { + Celsius { return $this.Degrees + 273.15 } + Fahrenheit { return ($this.Degrees + 459.67) * 5 / 9 } + } + return $this.Degrees + } + [float] ToCelsius() { + switch ($this.Scale) { + Fahrenheit { return ($this.Degrees - 32) * 5 / 9 } + Kelvin { return $this.Degrees - 273.15 } + } + return $this.Degrees + } + [float] ToFahrenheit() { + switch ($this.Scale) { + Celsius { return $this.Degrees * 9 / 5 + 32 } + Kelvin { return $this.Degrees * 9 / 5 - 459.67 } + } + return $this.Degrees + } + + [string] ToString( + [string]$Format, + [System.IFormatProvider]$FormatProvider + ) { + # If format isn't specified, use the defined scale. + if ([string]::IsNullOrEmpty($Format)) { + $Format = switch ($this.Scale) { + Celsius { 'C' } + Fahrenheit { 'F' } + Kelvin { 'K' } + } + } + # If format provider isn't specified, use the current culture. + if ($null -eq $FormatProvider) { + $FormatProvider = [CultureInfo]::CurrentCulture + } + # Format the temperature. + switch ($Format) { + 'C' { + return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C' + } + 'F' { + return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F' + } + 'K' { + return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K' + } + } + # If we get here, the format is invalid. + throw [System.FormatException]::new( + "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'" + ) + } + + [string] ToString([string]$Format) { + return $this.ToString($Format, $null) + } + + [string] ToString() { + return $this.ToString($null, $null) + } +} + +enum TemperatureScale { + Celsius = 0 + Fahrenheit = 1 + Kelvin = 2 +} +``` + +The output for the method overloads is shown in the following block. + +```powershell +$Temp = [Temperature]::new() +"The temperature is $Temp" +$Temp.ToString() +$Temp.ToString('K') +$Temp.ToString('F', $null) +``` + +```Output +The temperature is 0.00°C + +0.00°C + +273.15°K + +32.00°F +``` + +#### Implementing IEquatable + +Now that the **Temperature** class can be formatted for readability, users need +be able to check whether two instances of the class are equal. To support this +test, the class needs to implement the **System.IEquatable** interface. + +To implement the interface, the class needs to inherit from +**System.IEquatable** and define the `Equals()` instance method. The `Equals()` +method needs to have the following signature: + +```powershell +[bool] Equals([object]$Other) { + # Implementation +} +``` + +The signature that the interface requires is listed in the +[reference documentation][02]. + +For **Temperature**, the class should only support comparing two instances of +the class. For any other value or type, including `$null`, it should return +`$false`. When comparing two temperatures, the method should convert both +values to Kelvin, since temperatures can be equivalent even with different +scales. + +```powershell +[bool] Equals([object]$Other) { + # If the other object is null, we can't compare it. + if ($null -eq $Other) { + return $false + } + + # If the other object isn't a temperature, we can't compare it. + $OtherTemperature = $Other -as [Temperature] + if ($null -eq $OtherTemperature) { + return $false + } + + # Compare the temperatures as Kelvin. + return $this.ToKelvin() -eq $OtherTemperature.ToKelvin() +} +``` + +With the interface method implemented, the updated definition for +**Temperature** is: + +```powershell +class Temperature : System.IFormattable, System.IEquatable[object] { + [float] $Degrees + [TemperatureScale] $Scale + + Temperature() {} + Temperature([float] $Degrees) { $this.Degrees = $Degrees } + Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale } + Temperature([float] $Degrees, [TemperatureScale] $Scale) { + $this.Degrees = $Degrees + $this.Scale = $Scale + } + + [float] ToKelvin() { + switch ($this.Scale) { + Celsius { return $this.Degrees + 273.15 } + Fahrenheit { return ($this.Degrees + 459.67) * 5 / 9 } + } + return $this.Degrees + } + [float] ToCelsius() { + switch ($this.Scale) { + Fahrenheit { return ($this.Degrees - 32) * 5 / 9 } + Kelvin { return $this.Degrees - 273.15 } + } + return $this.Degrees + } + [float] ToFahrenheit() { + switch ($this.Scale) { + Celsius { return $this.Degrees * 9 / 5 + 32 } + Kelvin { return $this.Degrees * 9 / 5 - 459.67 } + } + return $this.Degrees + } + + [string] ToString( + [string]$Format, + [System.IFormatProvider]$FormatProvider + ) { + # If format isn't specified, use the defined scale. + if ([string]::IsNullOrEmpty($Format)) { + $Format = switch ($this.Scale) { + Celsius { 'C' } + Fahrenheit { 'F' } + Kelvin { 'K' } + } + } + # If format provider isn't specified, use the current culture. + if ($null -eq $FormatProvider) { + $FormatProvider = [CultureInfo]::CurrentCulture + } + # Format the temperature. + switch ($Format) { + 'C' { + return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C' + } + 'F' { + return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F' + } + 'K' { + return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K' + } + } + # If we get here, the format is invalid. + throw [System.FormatException]::new( + "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'" + ) + } + + [string] ToString([string]$Format) { + return $this.ToString($Format, $null) + } + + [string] ToString() { + return $this.ToString($null, $null) + } + + [bool] Equals([object]$Other) { + # If the other object is null, we can't compare it. + if ($null -eq $Other) { + return $false + } + + # If the other object isn't a temperature, we can't compare it. + $OtherTemperature = $Other -as [Temperature] + if ($null -eq $OtherTemperature) { + return $false + } + + # Compare the temperatures as Kelvin. + return $this.ToKelvin() -eq $OtherTemperature.ToKelvin() + } +} + +enum TemperatureScale { + Celsius = 0 + Fahrenheit = 1 + Kelvin = 2 +} +``` + +The following block shows how the updated class behaves: + +```powershell +$Celsius = [Temperature]::new() +$Fahrenheit = [Temperature]::new(32, 'Fahrenheit') +$Kelvin = [Temperature]::new([TemperatureScale]::Kelvin) + +@" +Temperatures are: $Celsius, $Fahrenheit, $Kelvin +`$Celsius.Equals(`$Fahrenheit) = $($Celsius.Equals($Fahrenheit)) +`$Celsius -eq `$Fahrenheit = $($Celsius -eq $Fahrenheit) +`$Celsius -ne `$Kelvin = $($Celsius -ne $Kelvin) +"@ +``` + +```Output +Temperatures are: 0.00°C, 32.00°F, 0.00°K + +$Celsius.Equals($Fahrenheit) = True +$Celsius -eq $Fahrenheit = True +$Celsius -ne $Kelvin = True +``` + +#### Implementing IComparable + +The last interface to implement for the **Temperature** class is +**System.IComparable**. When the class implements this interface, users can use +the `-lt`, `-le`, `-gt`, and `-ge` operators to compare instances of the class. + +To implement the interface, the class needs to inherit from +**System.IComparable** and define the `Equals()` instance method. The `Equals()` +method needs to have the following signature: + +```powershell +[int] CompareTo([Object]$Other) { + # Implementation +} +``` + +The signature that the interface requires is listed in the +[reference documentation][03]. + +For **Temperature**, the class should only support comparing two instances of +the class. Because the underlying type for the **Degrees** property, even when +converted to a different scale, is a floating point number, the method can rely +on the underlying type for the actual comparison. + +```powershell +[int] CompareTo([object]$Other) { + # If the other object's null, consider this instance "greater than" it + if ($null -eq $Other) { + return 1 + } + # If the other object isn't a temperature, we can't compare it. + $OtherTemperature = $Other -as [Temperature] + if ($null -eq $OtherTemperature) { + throw [System.ArgumentException]::new( + "Object must be of type 'Temperature'." + ) + } + # Compare the temperatures as Kelvin. + return $this.ToKelvin().CompareTo($OtherTemperature.ToKelvin()) +} +``` + +The final definition for the **Temperature** class is: + +```powershell +class Temperature : System.IFormattable, + System.IComparable, + System.IEquatable[object] { + # Instance properties + [float] $Degrees + [TemperatureScale] $Scale + + # Constructors + Temperature() {} + Temperature([float] $Degrees) { $this.Degrees = $Degrees } + Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale } + Temperature([float] $Degrees, [TemperatureScale] $Scale) { + $this.Degrees = $Degrees + $this.Scale = $Scale + } + + [float] ToKelvin() { + switch ($this.Scale) { + Celsius { return $this.Degrees + 273.15 } + Fahrenheit { return ($this.Degrees + 459.67) * 5 / 9 } + } + return $this.Degrees + } + [float] ToCelsius() { + switch ($this.Scale) { + Fahrenheit { return ($this.Degrees - 32) * 5 / 9 } + Kelvin { return $this.Degrees - 273.15 } + } + return $this.Degrees + } + [float] ToFahrenheit() { + switch ($this.Scale) { + Celsius { return $this.Degrees * 9 / 5 + 32 } + Kelvin { return $this.Degrees * 9 / 5 - 459.67 } + } + return $this.Degrees + } + + [string] ToString( + [string]$Format, + [System.IFormatProvider]$FormatProvider + ) { + # If format isn't specified, use the defined scale. + if ([string]::IsNullOrEmpty($Format)) { + $Format = switch ($this.Scale) { + Celsius { 'C' } + Fahrenheit { 'F' } + Kelvin { 'K' } + } + } + # If format provider isn't specified, use the current culture. + if ($null -eq $FormatProvider) { + $FormatProvider = [CultureInfo]::CurrentCulture + } + # Format the temperature. + switch ($Format) { + 'C' { + return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C' + } + 'F' { + return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F' + } + 'K' { + return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K' + } + } + # If we get here, the format is invalid. + throw [System.FormatException]::new( + "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'" + ) + } + + [string] ToString([string]$Format) { + return $this.ToString($Format, $null) + } + + [string] ToString() { + return $this.ToString($null, $null) + } + + [bool] Equals([object]$Other) { + # If the other object is null, we can't compare it. + if ($null -eq $Other) { + return $false + } + # If the other object isn't a temperature, we can't compare it. + $OtherTemperature = $Other -as [Temperature] + if ($null -eq $OtherTemperature) { + return $false + } + # Compare the temperatures as Kelvin. + return $this.ToKelvin() -eq $OtherTemperature.ToKelvin() + } + [int] CompareTo([object]$Other) { + # If the other object's null, consider this instance "greater than" it + if ($null -eq $Other) { + return 1 + } + # If the other object isn't a temperature, we can't compare it. + $OtherTemperature = $Other -as [Temperature] + if ($null -eq $OtherTemperature) { + throw [System.ArgumentException]::new( + "Object must be of type 'Temperature'." + ) + } + # Compare the temperatures as Kelvin. + return $this.ToKelvin().CompareTo($OtherTemperature.ToKelvin()) + } +} + +enum TemperatureScale { + Celsius = 0 + Fahrenheit = 1 + Kelvin = 2 +} +``` + +With the full definition, users can format and compare instances of the class +in PowerShell like any builtin type. + +```powershell +$Celsius = [Temperature]::new() +$Fahrenheit = [Temperature]::new(32, 'Fahrenheit') +$Kelvin = [Temperature]::new([TemperatureScale]::Kelvin) + +@" +Temperatures are: $Celsius, $Fahrenheit, $Kelvin +`$Celsius.Equals(`$Fahrenheit) = $($Celsius.Equals($Fahrenheit)) +`$Celsius.Equals(`$Kelvin) = $($Celsius.Equals($Kelvin)) +`$Celsius.CompareTo(`$Fahrenheit) = $($Celsius.CompareTo($Fahrenheit)) +`$Celsius.CompareTo(`$Kelvin) = $($Celsius.CompareTo($Kelvin)) +`$Celsius -lt `$Fahrenheit = $($Celsius -lt $Fahrenheit) +`$Celsius -le `$Fahrenheit = $($Celsius -le $Fahrenheit) +`$Celsius -eq `$Fahrenheit = $($Celsius -eq $Fahrenheit) +`$Celsius -gt `$Kelvin = $($Celsius -gt $Kelvin) +"@ +``` + +```Output +Temperatures are: 0.00°C, 32.00°F, 0.00°K +$Celsius.Equals($Fahrenheit) = True +$Celsius.Equals($Kelvin) = False +$Celsius.CompareTo($Fahrenheit) = 0 +$Celsius.CompareTo($Kelvin) = 1 +$Celsius -lt $Fahrenheit = False +$Celsius -le $Fahrenheit = True +$Celsius -eq $Fahrenheit = True +$Celsius -gt $Kelvin = True +``` + +### Example 3 - Inheriting from a generic base class + +This example shows how you can derive from a generic class like +**System.Collections.Generic.List**. + +#### Using a built-in class as the type parameter + +Run the following code block. It shows how a new class can inherit from a +generic type as long as the type parameter is already defined at parse time. + +```powershell +class ExampleStringList : System.Collections.Generic.List[string] {} + +$List = [ExampleStringList]::New() +$List.AddRange([string[]]@('a','b','c')) +$List.GetType() | Format-List -Property Name, BaseType +$List +``` + +```Output +Name : ExampleStringList +BaseType : System.Collections.Generic.List`1[System.String] + +a +b +c +``` + +#### Using a custom class as the type parameter + +The next code block first defines a new class, **ExampleItem**, +with a single instance property and the `ToString()` method. Then it defines +the **ExampleItemList** class inheriting from the +**System.Collections.Generic.List** base class with **ExampleItem** as the type +parameter. + +Copy the entire code block and run it as a single statement. + +```powershell +class ExampleItem { + [string] $Name + [string] ToString() { return $this.Name } +} +class ExampleItemList : System.Collections.Generic.List[ExampleItem] {} +``` + +```Output +ParentContainsErrorRecordException: An error occurred while creating the pipeline. +``` + +Running the entire code block raises an error because PowerShell hasn't loaded +the **ExampleItem** class into the runtime yet. You can't use class name as the +type parameter for the **System.Collections.Generic.List** base class yet. + +Run the following code blocks in the order they're defined. + +```powershell +class ExampleItem { + [string] $Name + [string] ToString() { return $this.Name } +} +``` + +```powershell +class ExampleItemList : System.Collections.Generic.List[ExampleItem] {} +``` + +This time, PowerShell doesn't raise any errors. Both classes are now defined. +Run the following code block to view the behavior of the new class. + +```powershell +$List = [ExampleItemList]::New() +$List.AddRange([ExampleItem[]]@( + [ExampleItem]@{ Name = 'Foo' } + [ExampleItem]@{ Name = 'Bar' } + [ExampleItem]@{ Name = 'Baz' } +)) +$List.GetType() | Format-List -Property Name, BaseType +$List +``` + +```output +Name : ExampleItemList +BaseType : System.Collections.Generic.List`1[ExampleItem] + +Name +---- +Foo +Bar +Baz +``` + +#### Deriving a generic with a custom type parameter in a module + +The following code blocks show how you can define a class that inherits from a +generic base class that uses a custom type for the type parameter. + +Save the following code block as `GenericExample.psd1`. + +```powershell +@{ + RootModule = 'GenericExample.psm1' + ModuleVersion = '0.1.0' + GUID = '2779fa60-0b3b-4236-b592-9060c0661ac2' +} +``` + +Save the following code block as `GenericExample.InventoryItem.psm1`. + +```powershell +class InventoryItem { + [string] $Name + [int] $Count + + InventoryItem() {} + InventoryItem([string]$Name) { + $this.Name = $Name + } + InventoryItem([string]$Name, [int]$Count) { + $this.Name = $Name + $this.Count = $Count + } + + [string] ToString() { + return "$($this.Name) ($($this.Count))" + } +} +``` + +Save the following code block as `GenericExample.psm1`. + +```powershell +using namespace System.Collections.Generic +using module ./GenericExample.InventoryItem.psm1 + +class Inventory : List[InventoryItem] {} + +# Define the types to export with type accelerators. +$ExportableTypes =@( + [InventoryItem] + [Inventory] +) +# Get the internal TypeAccelerators class to use its static methods. +$TypeAcceleratorsClass = [psobject].Assembly.GetType( + 'System.Management.Automation.TypeAccelerators' +) +# Ensure none of the types would clobber an existing type accelerator. +# If a type accelerator with the same name exists, throw an exception. +$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get +foreach ($Type in $ExportableTypes) { + if ($Type.FullName -in $ExistingTypeAccelerators.Keys) { + $Message = @( + "Unable to register type accelerator '$($Type.FullName)'" + 'Accelerator already exists.' + ) -join ' - ' + + throw [System.Management.Automation.ErrorRecord]::new( + [System.InvalidOperationException]::new($Message), + 'TypeAcceleratorAlreadyExists', + [System.Management.Automation.ErrorCategory]::InvalidOperation, + $Type.FullName + ) + } +} +# Add type accelerators for every exportable type. +foreach ($Type in $ExportableTypes) { + $TypeAcceleratorsClass::Add($Type.FullName, $Type) +} +# Remove type accelerators when the module is removed. +$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { + foreach($Type in $ExportableTypes) { + $TypeAcceleratorsClass::Remove($Type.FullName) + } +}.GetNewClosure() +``` + +> [!TIP] +> The root module adds the custom types to PowerShell's type accelerators. This +> pattern enables module users to immediately access IntelliSense and +> autocomplete for the custom types without needing to use the `using module` +> statement first. +> +> For more information about this pattern, see the "Exporting with type +> accelerators" section of [about_Classes][04]. + +Import the module and verify the output. + +```powershell +Import-Module ./GenericExample.psd1 + +$Inventory = [Inventory]::new() +$Inventory.GetType() | Format-List -Property Name, BaseType + +$Inventory.Add([InventoryItem]::new('Bucket', 2)) +$Inventory.Add([InventoryItem]::new('Mop')) +$Inventory.Add([InventoryItem]@{ Name = 'Broom' ; Count = 4 }) +$Inventory +``` + +```Output +Name : Inventory +BaseType : System.Collections.Generic.List`1[InventoryItem] + +Name Count +---- ----- +Bucket 2 +Mop 0 +Broom 4 +``` + +The module loads without errors because the **InventoryItem** class is defined +in a different module file than the **Inventory** class. Both classes are +available to module users. + +## Inheriting a base class + +When a class inherits from a base class, it inherits the properties and methods +of the base class. It doesn't inherit the base class constructors directly, +but it can call them. + +When the base class is defined in .NET rather than PowerShell, note that: + +- PowerShell classes can't inherit from sealed classes. +- When inheriting from a generic base class, the type parameter for the generic + class can't be the derived class. Using the derived class as the type + parameter raises a parse error. + +To see how inheritance and overriding works for derived classes, see +[Example 1][05]. + +### Derived class constructors + +Derived classes don't directly inherit the constructors of the base class. If +the base class defines a default constructor and the derived class doesn't +define any constructors, new instances of the derived class use the base class +default constructor. If the base class doesn't define a default constructor, +derived class must explicitly define at least one constructor. + +Derived class constructors can invoke a constructor from the base class with +the `base` keyword. If the derived class doesn't explicitly invoke a +constructor from the base class, it invokes the default constructor for the +base class instead. + +To invoke a nondefault base constructor, add `: base()` after the +constructor parameters and before the body block. + +```Syntax +class : { + () : () { + # initialization code + } +} +``` + +When defining a constructor that calls a base class constructor, the parameters +can be any of the following items: + +- The variable of any parameter on the derived class constructor. +- Any static value. +- Any expression that evaluates to a value of the parameter type. + +The **Illustration** class in [Example 1][05] shows how a derived class can use +the base class constructors. + +### Derived class methods + +When a class derives from a base class, it inherits the methods of the base +class and their overloads. Any method overloads defined on the base class, +including hidden methods, are available on the derived class. + +A derived class can override an inherited method overload by redefining it in +the class definition. To override the overload, the parameter types must be the +same as for the base class. The output type for the overload can be different. + +Unlike constructors, methods can't use the `: base()` syntax to +invoke a base class overload for the method. The redefined overload on the +derived class completely replaces the overload defined by the base class. To +call the base class method for an instance, cast the instance variable +(`$this`) to the base class before calling the method. + +The following snippet shows how a derived class can call the base class method. + +```powershell +class BaseClass { + [bool] IsTrue() { return $true } +} +class DerivedClass : BaseClass { + [bool] IsTrue() { return $false } + [bool] BaseIsTrue() { return ([BaseClass]$this).IsTrue() } +} + +@" +[BaseClass]::new().IsTrue() = $([BaseClass]::new().IsTrue()) +[DerivedClass]::new().IsTrue() = $([DerivedClass]::new().IsTrue()) +[DerivedClass]::new().BaseIsTrue() = $([DerivedClass]::new().BaseIsTrue()) +"@ +``` + +```Output +[BaseClass]::new().IsTrue() = True +[DerivedClass]::new().IsTrue() = False +[DerivedClass]::new().BaseIsTrue() = True +``` + +For an extended sample showing how a derived class can override inherited +methods, see the **Illustration** class in +[Example 1][05]. + +### Derived class properties + +When a class derives from a base class, it inherits the properties of the base +class. Any properties defined on the base class, including hidden properties, +are available on the derived class. + +A derived class can override an inherited property by redefining it in the +class definition. The property on the derived class uses the redefined type and +default value, if any. If the inherited property defined a default value and +the redefined property doesn't, the inherited property has no default value. + +If a derived class doesn't override a static property, accessing the static +property through the derived class accesses the static property of the base +class. Modifying the property value through the derived class modifies the +value on the base class. Any other derived class that doesn't override the +static property also uses the value of the property on the base class. Updating +the value of an inherited static property in a class that doesn't override the +property might have unintended effects for classes derived from the same base +class. + +[Example 1][05] shows how +derived classes that inherit, extend, and override the base class properties. + +### Deriving from generics + +When a class derives from a generic, the type parameter must already be defined +before PowerShell parses the derived class. If the type parameter for the +generic is a PowerShell class or enumeration defined in the same file or +code block, PowerShell raises an error. + +To derive a class from a generic base class with a custom type as the type +parameter, define the class or enumeration for the type parameter in a +different file or module and use the `using module` statement to load the type +definition. + +For an example showing how to inherit from a generic base class, see +[Example 3][06]. + +### Useful classes to inherit + +There are a few classes that can be useful to inherit when authoring PowerShell +modules. This section lists a few base classes and what a class derived from +them can be used for. + +- **System.Attribute** - Derive classes to define attributes that can be used + for variables, parameters, class and enumeration definitions, and more. +- **System.Management.Automation.ArgumentTransformationAttribute** - Derive + classes to handle converting input for a variable or parameter into a + specific data type. +- **System.Management.Automation.ValidateArgumentsAttribute** - Derive classes + to apply custom validation to variables, parameters, and class properties. +- **System.Collections.Generic.List** - Derive classes to make creating and + managing lists of a specific data type easier. +- **System.Exception** - Derive classes to define custom errors. + +## Implementing interfaces + +A PowerShell class that implements an interface must implement all the members +of that interface. Omitting the implementation interface members causes a +parse-time error in the script. + +> [!NOTE] +> PowerShell doesn't support declaring new interfaces in PowerShell script. +> Instead, interfaces must be declared in .NET code and added to the session +> with the `Add-Type` cmdlet or the `using assembly` statement. + +When a class implements an interface, it can be used like any other class that +implements that interface. Some commands and operations limit their supported +types to classes that implement a specific interface. + +To review a sample implementation of interfaces, see [Example 2][07]. + +### Useful interfaces to implement + +There are a few interface classes that can be useful to inherit when authoring +PowerShell modules. This section lists a few base classes and what a class +derived from them can be used for. + +- **System.IEquatable** - This interface enables users to compare two instances + of the class. When a class doesn't implement this interface, PowerShell + checks for equivalency between two instances using reference equality. In + other words, an instance of the class only equals itself, even if the + property values on two instances are the same. +- **System.IComparable** - This interface enables users to compare instances of + the class with the `-le`, `-lt`, `-ge`, and `-gt` comparison operators. When + a class doesn't implement this interface, those operators raise an error. +- **System.IFormattable** - This interface enables users to format instances of + the class into different strings. This is useful for classes that have more + than one standard string representation, like budget items, bibliographies, + and temperatures. +- **System.IConvertible** - This interface enables users to convert instances + of the class to other runtime types. This is useful for classes that have an + underlying numerical value or can be converted to one. + +## Limitations + +- PowerShell doesn't support defining interfaces in script code. + + Workaround: Define interfaces in C# and reference the assembly that defines + the interfaces. +- PowerShell classes can only inherit from one base class. + + Workaround: Class inheritance is transitive. A derived class can inherit from + another derived class to get the properties and methods of a base class. +- When inheriting from a generic class or interface, the type parameter for the + generic must already be defined. A class can't define itself as the type + parameter for a class or interface. + + Workaround: To derive from a generic base class or interface, define the + custom type in a different `.psm1` file and use the `using module` statement + to load the type. There's no workaround for a custom type to use itself as + the type parameter when inheriting from a generic. + +## See Also + +- [about_Classes][08] +- [about_Classes_Constructors][09] +- [about_Classes_Methods][10] +- [about_Classes_Properties][11] + + +[01]: /dotnet/api/system.iformattable#methods +[02]: /dotnet/api/system.iequatable-1#methods +[03]: /dotnet/api/system.icomparable#methods +[04]: about_Classes.md#exporting-classes-with-type-accelerators +[05]: #example-1---inheriting-and-overriding-from-a-base-class +[06]: #example-3---inheriting-from-a-generic-base-class +[07]: #example-2---implementing-interfaces +[08]: about_Classes.md +[09]: about_Classes_Constructors.md +[10]: about_Classes_Inheritance.md +[11]: about_Classes_Properties.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Methods.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Methods.md new file mode 100644 index 000000000000..2d71eddc047b --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Methods.md @@ -0,0 +1,812 @@ +--- +description: Describes how to define methods for PowerShell classes. +Locale: en-US +ms.date: 11/13/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_methods?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Classes_Methods +--- + +# about_Classes_Methods + +## Short description + +Describes how to define methods for PowerShell classes. + +## Long description + +Methods define the actions that a class can perform. Methods can take +parameters that specify input data. Methods always define an output type. If a +method doesn't return any output, it must have the **Void** output type. If a +method doesn't explicitly define an output type, the method's output type is +**Void**. + +In class methods, no objects get sent to the pipeline except those specified in +the `return` statement. There's no accidental output to the pipeline from the +code. + +> [!NOTE] +> This is fundamentally different from how PowerShell functions handle output, +> where everything goes to the pipeline. + +Nonterminating errors written to the error stream from inside a class method +aren't passed through. You must use `throw` to surface a terminating error. +Using the `Write-*` cmdlets, you can still write to PowerShell's output streams +from within a class method. The cmdlets respect the [preference variables][01] +in the calling scope. However, you should avoid using the `Write-*` cmdlets so +that the method only outputs objects using the `return` statement. + +Class methods can reference the current instance of the class object by using +the `$this` automatic variable to access properties and other methods defined +in the current class. The `$this` automatic variable isn't available in static +methods. + +Class methods can have any number of attributes, including the [hidden][02] and +[static][03] attributes. + +## Syntax + +Class methods use the following syntaxes: + +### One-line syntax + +```Syntax +[[]...] [hidden] [static] [] ([]) { } +``` + +### Multiline syntax + +```Syntax +[[]...] +[hidden] +[static] +[] ([]) { + +} +``` + +## Examples + +### Example 1 - Minimal method definition + +The `GetVolume()` method of the **ExampleCube1** class returns the volume of +the cube. It defines the output type as a floating number and returns the +result of multiplying the **Height**, **Length**, and **Width** properties of +the instance. + +```powershell +class ExampleCube1 { + [float] $Height + [float] $Length + [float] $Width + + [float] GetVolume() { return $this.Height * $this.Length * $this.Width } +} + +$box = [ExampleCube1]@{ + Height = 2 + Length = 2 + Width = 3 +} + +$box.GetVolume() +``` + +```Output +12 +``` + +### Example 2 - Method with parameters + +The `GeWeight()` method takes a floating number input for the density of the +cube and returns the weight of the cube, calculated as volume multiplied by +density. + +```powershell +class ExampleCube2 { + [float] $Height + [float] $Length + [float] $Width + + [float] GetVolume() { return $this.Height * $this.Length * $this.Width } + [float] GetWeight([float]$Density) { + return $this.GetVolume() * $Density + } +} + +$cube = [ExampleCube2]@{ + Height = 2 + Length = 2 + Width = 3 +} + +$cube.GetWeight(2.5) +``` + +```Output +30 +``` + +### Example 3 - Method without output + +This example defines the `Validate()` method with the output type as +**System.Void**. This method returns no output. Instead, if the validation +fails, it throws an error. The `GetVolume()` method calls `Validate()` before +calculating the volume of the cube. If validation fails, the method terminates +before the calculation. + +```powershell +class ExampleCube3 { + [float] $Height + [float] $Length + [float] $Width + + [float] GetVolume() { + $this.Validate() + + return $this.Height * $this.Length * $this.Width + } + + [void] Validate() { + $InvalidProperties = @() + foreach ($Property in @('Height', 'Length', 'Width')) { + if ($this.$Property -le 0) { + $InvalidProperties += $Property + } + } + + if ($InvalidProperties.Count -gt 0) { + $Message = @( + 'Invalid cube properties' + "('$($InvalidProperties -join "', '")'):" + "Cube dimensions must all be positive numbers." + ) -join ' ' + throw $Message + } + } +} + +$Cube = [ExampleCube3]@{ Length = 1 ; Width = -1 } +$Cube + +$Cube.GetVolume() +``` + +```Output +Height Length Width +------ ------ ----- + 0.00 1.00 -1.00 + +Exception: +Line | + 20 | throw $Message + | ~~~~~~~~~~~~~~ + | Invalid cube properties ('Height', 'Width'): Cube dimensions must + | all be positive numbers. +``` + +The method throws an exception because the **Height** and **Width** properties +are invalid, preventing the class from calculating the current volume. + +### Example 4 - Static method with overloads + +The **ExampleCube4** class defines the static method `GetVolume()` with two +overloads. The first overload has parameters for the dimensions of the cube and +a flag to indicate whether the method should validate the input. + +The second overload only includes the numeric inputs. It calls the first +overload with `$Static` as `$true`. The second overload gives users a way to +call the method without always having to define whether to strictly validate +the input. + +The class also defines `GetVolume()` as an instance (nonstatic) method. This +method calls the second static overload, ensuring that the instance +`GetVolume()` method always validates the cube's dimensions before returning +the output value. + +```powershell +class ExampleCube4 { + [float] $Height + [float] $Length + [float] $Width + + static [float] GetVolume( + [float]$Height, + [float]$Length, + [float]$Width, + [boolean]$Strict + ) { + $Signature = "[ExampleCube4]::GetVolume({0}, {1}, {2}, {3})" + $Signature = $Signature -f $Height, $Length, $Width, $Strict + Write-Verbose "Called $Signature" + + if ($Strict) { + [ValidateScript({$_ -gt 0 })]$Height = $Height + [ValidateScript({$_ -gt 0 })]$Length = $Length + [ValidateScript({$_ -gt 0 })]$Width = $Width + } + + return $Height * $Length * $Width + } + + static [float] GetVolume([float]$Height, [float]$Length, [float]$Width) { + $Signature = "[ExampleCube4]::GetVolume($Height, $Length, $Width)" + Write-Verbose "Called $Signature" + + return [ExampleCube4]::GetVolume($Height, $Length, $Width, $true) + } + + [float] GetVolume() { + Write-Verbose "Called `$this.GetVolume()" + return [ExampleCube4]::GetVolume( + $this.Height, + $this.Length, + $this.Width + ) + } +} + +$VerbosePreference = 'Continue' +$Cube = [ExampleCube4]@{ Height = 2 ; Length = 2 } +$Cube.GetVolume() +``` + +```Output +VERBOSE: Called $this.GetVolume() +VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0) +VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, True) + +MetadataError: +Line | + 19 | [ValidateScript({$_ -gt 0 })]$Width = $Width + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | The variable cannot be validated because the value 0 is not a valid + | value for the Width variable. +``` + +The verbose messages in the method definitions show how the initial call to +`$this.GetVolume()` calls the static method. + +Calling the static method directly with the **Strict** parameter as `$false` +returns `0` for the volume. + +```powershell +[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false) +``` + +```Output +VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False) +0 +``` + +## Method signatures and overloads + +Every class method has a unique signature that defines how to call the method. +The method's output type, name, and parameters define the method signature. + +When a class defines more than one method with the same name, the definitions +of that method are _overloads_. Overloads for a method must have different +parameters. A method can't define two implementations with the same parameters, +even if the output types are different. + +The following class defines two methods, `Shuffle()` and `Deal()`. The `Deal()` +method defines two overloads, one without any parameters and the other with the +**Count** parameter. + +```powershell +class CardDeck { + [string[]]$Cards = @() + hidden [string[]]$Dealt = @() + hidden [string[]]$Suits = @('Clubs', 'Diamonds', 'Hearts', 'Spades') + hidden [string[]]$Values = 2..10 + @('Jack', 'Queen', 'King', 'Ace') + + CardDeck() { + foreach($Suit in $this.Suits) { + foreach($Value in $this.Values) { + $this.Cards += "$Value of $Suit" + } + } + $this.Shuffle() + } + + [void] Shuffle() { + $this.Cards = $this.Cards + $this.Dealt | Where-Object -FilterScript { + -not [string]::IsNullOrEmpty($_) + } | Get-Random -Count $this.Cards.Count + } + + [string] Deal() { + if ($this.Cards.Count -eq 0) { throw "There are no cards left." } + + $Card = $this.Cards[0] + $this.Cards = $this.Cards[1..$this.Cards.Count] + $this.Dealt += $Card + + return $Card + } + + [string[]] Deal([int]$Count) { + if ($Count -gt $this.Cards.Count) { + throw "There are only $($this.Cards.Count) cards left." + } elseif ($Count -lt 1) { + throw "You must deal at least 1 card." + } + + return (1..$Count | ForEach-Object { $this.Deal() }) + } +} +``` + +## Method output + +By default, methods don't have any output. If a method signature includes an +explicit output type other than **Void**, the method must return an object of +that type. Methods don't emit any output except when the `return` keyword +explicitly returns an object. + +## Method parameters + +Class methods can define input parameters to use in the method body. Method +parameters are enclosed in parentheses and are separated by commas. Empty +parentheses indicate that the method requires no parameters. + +Parameters can be defined on a single line or multiple lines. The following +blocks show the syntax for method parameters. + +```Syntax +([[]]$[, [[]]$]) +``` + +```Syntax +( + [[]]$[, + [[]]$] +) +``` + +Method parameters can be strongly typed. If a parameter isn't typed, the method +accepts any object for that parameter. If the parameter is typed, the method +tries to convert the value for that parameter to the correct type, throwing an +exception if the input can't be converted. + +Method parameters can't define default values. All method parameters are +mandatory. + +Method parameters can't have any other attributes. This prevents methods from +using parameters with the `Validate*` attributes. For more information about +the validation attributes, see [about_Functions_Advanced_Parameters][04]. + +You can use one of the following patterns to add validation to method +parameters: + +1. Reassign the parameters to the same variables with the required validation + attributes. This works for both static and instance methods. For an example + of this pattern, see [Example 4][05]. +1. Use `Update-TypeData` to define a `ScriptMethod` that uses validation + attributes on the parameters directly. This only works for instance methods. + For more information, see the + [Defining instance methods with Update-TypeData][06] section. + +## Automatic variables in methods + +Not all automatic variables are available in methods. The following list +includes automatic variables and suggestions for whether and how to use them in +PowerShell class methods. Automatic variables not included in the list aren't +available to class methods. + +- `$?` - Access as normal. +- `$_` - Access as normal. +- `$args` - Use the explicit parameter variables instead. +- `$ConsoleFileName` - Access as `$Script:ConsoleFileName` instead. +- `$Error` - Access as normal. +- `$EnabledExperimentalFeatures` - Access as + `$Script:EnabledExperimentalFeatures` instead. +- `$Event` - Access as normal. +- `$EventArgs` - Access as normal. +- `$EventSubscriber` - Access as normal. +- `$ExecutionContext` - Access as `$Script:ExecutionContext` instead. +- `$false` - Access as normal. +- `$foreach` - Access as normal. +- `$HOME` - Access as `$Script:HOME` instead. +- `$Host` - Access as `$Script:Host` instead. +- `$input` - Use the explicit parameter variables instead. +- `$IsCoreCLR` - Access as `$Script:IsCoreCLR` instead. +- `$IsLinux` - Access as `$Script:IsLinux` instead. +- `$IsMacOS` - Access as `$Script:IsMacOS` instead. +- `$IsWindows` - Access as `$Script:IsWindows` instead. +- `$LASTEXITCODE` - Access as normal. +- `$Matches` - Access as normal. +- `$MyInvocation` - Access as normal. +- `$NestedPromptLevel` - Access as normal. +- `$null` - Access as normal. +- `$PID` - Access as `$Script:PID` instead. +- `$PROFILE` - Access as `$Script:PROFILE` instead. +- `$PSBoundParameters` - Don't use this variable. It's intended for cmdlets and + functions. Using it in a class may have unexpected side effects. +- `$PSCmdlet` - Don't use this variable. It's intended for cmdlets and + functions. Using it in a class may have unexpected side effects. +- `$PSCommandPath` - Access as normal. +- `$PSCulture` - Access as `$Script:PSCulture` instead. +- `$PSEdition` - Access as `$Script:PSEdition` instead. +- `$PSHOME` - Access as `$Script:PSHOME` instead. +- `$PSItem` - Access as normal. +- `$PSScriptRoot` - Access as normal. +- `$PSSenderInfo` - Access as `$Script:PSSenderInfo` instead. +- `$PSUICulture` - Access as `$Script:PSUICulture` instead. +- `$PSVersionTable` - Access as `$Script:PSVersionTable` instead. +- `$PWD` - Access as normal. +- `$Sender` - Access as normal. +- `$ShellId` - Access as `$Script:ShellId` instead. +- `$StackTrace` - Access as normal. +- `$switch` - Access as normal. +- `$this` - Access as normal. In a class method, `$this` is always the current + instance of the class. You can access the class properties and methods with + it. It's not available in static methods. +- `$true` - Access as normal. + +For more information about automatic variables, see +[about_Automatic_Variables][07]. + +## Hidden methods + +You can hide methods of a class by declaring them with the `hidden` keyword. +Hidden class methods are: + +- Not included in the list of class members returned by the `Get-Member` + cmdlet. To show hidden methods with `Get-Member`, use the **Force** + parameter. +- Not displayed in tab completion or IntelliSense unless the completion occurs + in the class that defines the hidden method. +- Public members of the class. They can be called and inherited. Hiding a + method doesn't make it private. It only hides the method as described in the + previous points. + +> [!NOTE] +> When you hide any overload for a method, that method is removed from +> IntelliSense, completion results, and the default output for `Get-Member`. + +For more information about the `hidden` keyword, see [about_Hidden][08]. + +## Static methods + +You can define a method as belonging to the class itself instead of instances +of the class by declaring the method with the `static` keyword. Static class +methods: + +- Are always available, independent of class instantiation. +- Are shared across all instances of the class. +- Are always available. +- Can't access instance properties of the class. They can only access static + properties. +- Live for the entire session span. + +## Derived class methods + +When a class derives from a base class, it inherits the methods of the base +class and their overloads. Any method overloads defined on the base class, +including hidden methods, are available on the derived class. + +A derived class can override an inherited method overload by redefining it in +the class definition. To override the overload, the parameter types must be the +same as for the base class. The output type for the overload can be different. + +Unlike constructors, methods can't use the `: base()` syntax to +invoke a base class overload for the method. The redefined overload on the +derived class completely replaces the overload defined by the base class. + +The following example shows the behavior for static and instance methods on +derived classes. + +The base class defines: + +- The static methods `Now()` for returning the current time and `DaysAgo()` for + returning a date in the past. +- The instance property **TimeStamp** and a `ToString()` instance method that + returns the string representation of that property. This ensures that when an + instance is used in a string it converts to the datetime string instead of + the class name. +- The instance method `SetTimeStamp()` with two overloads. When the method is + called without parameters, it sets the **TimeStamp** to the current time. + When the method is called with a **DateTime**, it sets the **TimeStamp** to + that value. + +```powershell +class BaseClass { + static [datetime] Now() { + return Get-Date + } + static [datetime] DaysAgo([int]$Count) { + return [BaseClass]::Now().AddDays(-$Count) + } + + [datetime] $TimeStamp = [BaseClass]::Now() + + [string] ToString() { + return $this.TimeStamp.ToString() + } + + [void] SetTimeStamp([datetime]$TimeStamp) { + $this.TimeStamp = $TimeStamp + } + [void] SetTimeStamp() { + $this.TimeStamp = [BaseClass]::Now() + } +} +``` + +The next block defines classes derived from **BaseClass**: + +- **DerivedClassA** inherits from **BaseClass** without any overrides. +- **DerivedClassB** overrides the `DaysAgo()` static method to return a string + representation instead of the **DateTime** object. It also overrides the + `ToString()` instance method to return the timestamp as an ISO8601 date + string. +- **DerivedClassC** overrides the parameterless overload of the + `SetTimeStamp()` method so that setting the timestamp without parameters sets + the date to 10 days before the current date. + +```powershell +class DerivedClassA : BaseClass {} +class DerivedClassB : BaseClass { + static [string] DaysAgo([int]$Count) { + return [BaseClass]::DaysAgo($Count).ToString('yyyy-MM-dd') + } + [string] ToString() { + return $this.TimeStamp.ToString('yyyy-MM-dd') + } +} +class DerivedClassC : BaseClass { + [void] SetTimeStamp() { + $this.SetTimeStamp([BaseClass]::Now().AddDays(-10)) + } +} +``` + +The following block shows the output of the static `Now()` method for the +defined classes. The output is the same for every class, because the derived +classes don't override the base class implementation of the method. + +```powershell +"[BaseClass]::Now() => $([BaseClass]::Now())" +"[DerivedClassA]::Now() => $([DerivedClassA]::Now())" +"[DerivedClassB]::Now() => $([DerivedClassB]::Now())" +"[DerivedClassC]::Now() => $([DerivedClassC]::Now())" +``` + +```Output +[BaseClass]::Now() => 11/06/2023 09:41:23 +[DerivedClassA]::Now() => 11/06/2023 09:41:23 +[DerivedClassB]::Now() => 11/06/2023 09:41:23 +[DerivedClassC]::Now() => 11/06/2023 09:41:23 +``` + +The next block calls the `DaysAgo()` static method of each class. Only the +output for **DerivedClassB** is different, because it overrode the base +implementation. + +```powershell +"[BaseClass]::DaysAgo(3) => $([BaseClass]::DaysAgo(3))" +"[DerivedClassA]::DaysAgo(3) => $([DerivedClassA]::DaysAgo(3))" +"[DerivedClassB]::DaysAgo(3) => $([DerivedClassB]::DaysAgo(3))" +"[DerivedClassC]::DaysAgo(3) => $([DerivedClassC]::DaysAgo(3))" +``` + +```Output +[BaseClass]::DaysAgo(3) => 11/03/2023 09:41:38 +[DerivedClassA]::DaysAgo(3) => 11/03/2023 09:41:38 +[DerivedClassB]::DaysAgo(3) => 2023-11-03 +[DerivedClassC]::DaysAgo(3) => 11/03/2023 09:41:38 +``` + +The following block shows the string presentation of a new instance for each +class. The representation for **DerivedClassB** is different because it +overrode the `ToString()` instance method. + +```powershell +"`$base = [BaseClass]::New() => $($base = [BaseClass]::New(); $base)" +"`$a = [DerivedClassA]::New() => $($a = [DerivedClassA]::New(); $a)" +"`$b = [DerivedClassB]::New() => $($b = [DerivedClassB]::New(); $b)" +"`$c = [DerivedClassC]::New() => $($c = [DerivedClassC]::New(); $c)" +``` + +```Output +$base = [BaseClass]::New() => 11/6/2023 9:44:57 AM +$a = [DerivedClassA]::New() => 11/6/2023 9:44:57 AM +$b = [DerivedClassB]::New() => 2023-11-06 +$c = [DerivedClassC]::New() => 11/6/2023 9:44:57 AM +``` + +The next block calls the `SetTimeStamp()` instance method for each instance, +setting the **TimeStamp** property to a specific date. Each instance has the +same date, because none of the derived classes override the parameterized +overload for the method. + +```powershell +[datetime]$Stamp = '2024-10-31' +"`$base.SetTimeStamp(`$Stamp) => $($base.SetTimeStamp($Stamp) ; $base)" +"`$a.SetTimeStamp(`$Stamp) => $($a.SetTimeStamp($Stamp); $a)" +"`$b.SetTimeStamp(`$Stamp) => $($b.SetTimeStamp($Stamp); $b)" +"`$c.SetTimeStamp(`$Stamp) => $($c.SetTimeStamp($Stamp); $c)" +``` + +```Output +$base.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM +$a.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM +$b.SetTimeStamp($Stamp) => 2024-10-31 +$c.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM +``` + +The last block calls `SetTimeStamp()` without any parameters. The output shows +that the value for the **DerivedClassC** instance is set to 10 days before the +others. + +```powershell +"`$base.SetTimeStamp() => $($base.SetTimeStamp() ; $base)" +"`$a.SetTimeStamp() => $($a.SetTimeStamp(); $a)" +"`$b.SetTimeStamp() => $($b.SetTimeStamp(); $b)" +"`$c.SetTimeStamp() => $($c.SetTimeStamp(); $c)" +``` + +```Output +$base.SetTimeStamp() => 11/6/2023 9:53:58 AM +$a.SetTimeStamp() => 11/6/2023 9:53:58 AM +$b.SetTimeStamp() => 2023-11-06 +$c.SetTimeStamp() => 10/27/2023 9:53:58 AM +``` + +## Defining instance methods with Update-TypeData + +Beyond declaring methods directly in the class definition, you can define +methods for instances of a class in the static constructor using the +`Update-TypeData` cmdlet. + +Use this snippet as a starting point for the pattern. Replace the placeholder +text in angle brackets as needed. + +```powershell +class { + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberName = '' + MemberType = 'ScriptMethod' + Value = { + param() + + + } + } + ) + + static () { + $TypeName = [].Name + foreach ($Definition in []::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } +} +``` + +> [!TIP] +> The `Add-Member` cmdlet can add properties and methods to a class in +> non-static constructors, but the cmdlet runs every time the constructor is +> called. Using `Update-TypeData` in the static constructor ensures that the +> code for adding the members to the class only needs to run once in a session. + +### Defining methods with default parameter values and validation attributes + +Methods defined directly in a class declaration can't define default values or +validation attributes on the method parameters. To define class methods with +default values or validation attributes, they must be defined as +**ScriptMethod** members. + +In this example, the **CardDeck** class defines a `Draw()` method that uses +both a validation attribute and a default value for the **Count** parameter. + +```powershell +class CookieJar { + [int] $Cookies = 12 + + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberName = 'Eat' + MemberType = 'ScriptMethod' + Value = { + param( + [ValidateScript({ $_ -ge 1 -and $_ -le $this.Cookies })] + [int] $Count = 1 + ) + + $this.Cookies -= $Count + if ($Count -eq 1) { + "You ate 1 cookie. There are $($this.Cookies) left." + } else { + "You ate $Count cookies. There are $($this.Cookies) left." + } + } + } + ) + + static CookieJar() { + $TypeName = [CookieJar].Name + foreach ($Definition in [CookieJar]::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } +} + +$Jar = [CookieJar]::new() +$Jar.Eat(1) +$Jar.Eat() +$Jar.Eat(20) +$Jar.Eat(6) +``` + +```Output +You ate 1 cookie. There are 11 left. + +You ate 1 cookie. There are 10 left. + +MethodInvocationException: +Line | + 36 | $Jar.Eat(20) + | ~~~~~~~~~~~~ + | Exception calling "Eat" with "1" argument(s): "The attribute + | cannot be added because variable Count with value 20 would no + | longer be valid." + +You ate 6 cookies. There are 4 left. +``` + +> [!NOTE] +> While this pattern works for validation attributes, notice that the exception +> is misleading, referencing an inability to add an attribute. It might be a +> better user experience to explicitly check the value for the parameter and +> raise a meaningful error instead. That way, users can understand why they're +> seeing the error and what to do about it. + +## Limitations + +PowerShell class methods have the following limitations: + +- Method parameters can't use any attributes, including validation attributes. + + Workaround: Reassign the parameters in the method body with the validation + attribute or define the method in the static constructor with the + `Update-TypeData` cmdlet. +- Method parameters can't define default values. The parameters are always + mandatory. + + Workaround: Define the method in the static constructor with the + `Update-TypeData` cmdlet. +- Methods are always public, even when they're hidden. They can be overridden + when the class is inherited. + + Workaround: None. +- If any overload of a method is hidden, every overload for that method is + treated as hidden too. + + Workaround: None. + +## See also + +- [about_Automatic_Variables][07] +- [about_Classes][09] +- [about_Classes_Constructors][10] +- [about_Classes_Inheritance][11] +- [about_Classes_Properties][12] +- [about_Using][13] + + +[01]: about_Preference_Variables.md +[02]: #hidden-methods +[03]: #static-methods +[04]: about_functions_advanced_parameters.md#parameter-and-variable-validation-attributes +[05]: #example-4---static-method-with-overloads +[06]: #defining-instance-methods-with-update-typedata +[07]: about_Automatic_Variables.md +[08]: about_Hidden.md +[09]: about_Classes.md +[10]: about_Classes_Constructors.md +[11]: about_Classes_Inheritance.md +[12]: about_Classes_Properties.md +[13]: about_Using.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Properties.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Properties.md new file mode 100644 index 000000000000..3a2df6bcda1d --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Classes_Properties.md @@ -0,0 +1,959 @@ +--- +description: Describes how to define properties for PowerShell classes. +Locale: en-US +ms.date: 11/13/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_properties?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Classes_Properties +--- + +# about_Classes_Properties + +## Short description + +Describes how to define properties for PowerShell classes. + +## Long description + +Properties are members of the class that contain data. Properties are declared +as variables in the class scope. A property can be of any built-in type or an +instance of another class. Classes can zero or more properties. Classes don't +have a maximum property count. + +Class properties can have any number of attributes, including the [hidden][01] +and [static][02] attributes. Every property definition must include a type for +the property. You can define a default value for a property. + +## Syntax + +Class properties use the following syntaxes: + +### One-line syntax + +```Syntax +[[]...] [] $ [= ] +``` + +### Multiline syntax + +```Syntax +[[]...] +[] +$ [= ] +``` + +## Examples + +### Example 1 - Minimal class properties + +The properties of the **ExampleProject1** class use built-in types without any +attributes or default values. + +```powershell +class ExampleProject1 { + [string] $Name + [int] $Size + [bool] $Completed + [string] $Assignee + [datetime] $StartDate + [datetime] $EndDate + [datetime] $DueDate +} + +[ExampleProject1]::new() + +$null -eq ([ExampleProject1]::new()).Name +``` + +```Output +Name : +Size : 0 +Completed : False +StartDate : 1/1/0001 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM + +True +``` + +The default value for the **Name** and **Assignee** properties is `$null` +because they're typed as strings, which is a reference type. The other +properties have the default value for their defined type, because they're +value type properties. For more information on the default values for +properties, see [Default property values][03]. + +### Example 2 - Class properties with custom types + +The properties for **ExampleProject2** include a custom enumeration and class +defined in PowerShell before the **ExampleProject2** class. + +```powershell +enum ProjectState { + NotTriaged + ReadyForWork + Committed + Blocked + InProgress + Done +} + +class ProjectAssignee { + [string] $DisplayName + [string] $UserName + + [string] ToString() { + return "$($this.DisplayName) ($($this.UserName))" + } +} + +class ExampleProject2 { + [string] $Name + [int] $Size + [ProjectState] $State + [ProjectAssignee] $Assignee + [datetime] $StartDate + [datetime] $EndDate + [datetime] $DueDate +} + +[ExampleProject2]@{ + Name = 'Class Property Documentation' + Size = 8 + State = 'InProgress' + Assignee = @{ + DisplayName = 'Mikey Lombardi' + UserName = 'michaeltlombardi' + } + StartDate = '2023-10-23' + DueDate = '2023-10-27' +} +``` + +```Output +Name : Class Property Documentation +Size : 8 +State : InProgress +Assignee : Mikey Lombardi (michaeltlombardi) +StartDate : 10/23/2023 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 10/27/2023 12:00:00 AM +``` + +### Example 3 - Class property with a validation attribute + +The **ExampleProject3** class defines the **Size** property as an integer that +must be greater than or equal to 0 and less than or equal to 16. It uses the +**ValidateRange** attribute to limit the value. + +```powershell +class ExampleProject3 { + [string] $Name + [ValidateRange(0, 16)] [int] $Size + [bool] $Completed + [string] $Assignee + [datetime] $StartDate + [datetime] $EndDate + [datetime] $DueDate +} + +$project = [ExampleProject3]::new() +$project +``` + +```Output +Name : +Size : 0 +Completed : False +Assignee : +StartDate : 1/1/0001 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM +``` + +When **ExampleProject3** instantiates, the **Size** defaults to 0. Setting the +property to a value within the valid range updates the value. + +```powershell +$project.Size = 8 +$project +``` + +```Output +Name : +Size : 8 +Completed : False +Assignee : +StartDate : 1/1/0001 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM +``` + +When **Size** is set to an invalid value outside the range, PowerShell raises +an exception and the value isn't changed. + +```powershell +$project.Size = 32 +$project.Size = -1 + +$project +``` + +```Output +SetValueInvocationException: +Line | + 1 | $project.Size = 32 + | ~~~~~~~~~~~~~~~~~~ + | Exception setting "Size": "The 32 argument is greater than the + | maximum allowed range of 16. Supply an argument that is less than + | or equal to 16 and then try the command again." + +SetValueInvocationException: +Line | + 2 | $project.Size = -1 + | ~~~~~~~~~~~~~~~~~~ + | Exception setting "Size": "The -1 argument is less than the minimum + | allowed range of 0. Supply an argument that is greater than or + | equal to 0 and then try the command again." + +Name : +Size : 8 +Completed : False +Assignee : +StartDate : 1/1/0001 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM +``` + +### Example 4 - Class property with an explicit default value + +The **ExampleProject4** class defaults the value for the **StartDate** property +to the current date. + +```powershell +class ExampleProject4 { + [string] $Name + [int] $Size + [bool] $Completed + [string] $Assignee + [datetime] $StartDate = (Get-Date).Date + [datetime] $EndDate + [datetime] $DueDate +} + +[ExampleProject4]::new() + +[ExampleProject4]::new().StartDate -eq (Get-Date).Date +``` + +```Output +Name : +Size : 0 +Completed : False +Assignee : +StartDate : 10/23/2023 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM + +True +``` + +### Example 5 - Hidden class property + +The **Guid** property of the **ExampleProject5** class has the `hidden` +keyword. The **Guid** property doesn't show in the default output for the +class or in the list of properties returned by `Get-Member`. + +```powershell +class ExampleProject5 { + [string] $Name + [int] $Size + [bool] $Completed + [string] $Assignee + [datetime] $StartDate + [datetime] $EndDate + [datetime] $DueDate + hidden [string] $Guid = (New-Guid).Guid +} + +$project = [ExampleProject5]::new() + +"Project GUID: $($project.Guid)" + +$project + +$project | Get-Member -MemberType Properties | Format-Table +``` + +```Output +Project GUID: c72cef84-057c-4649-8940-13490dcf72f0 + +Name : +Size : 0 +Completed : False +Assignee : +StartDate : 1/1/0001 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM + + + TypeName: ExampleProject5 + +Name MemberType Definition +---- ---------- ---------- +Assignee Property string Assignee {get;set;} +Completed Property bool Completed {get;set;} +DueDate Property datetime DueDate {get;set;} +EndDate Property datetime EndDate {get;set;} +Name Property string Name {get;set;} +Size Property int Size {get;set;} +StartDate Property datetime StartDate {get;set;} +``` + +### Example 6 - Static class property + +The **ExampleProject6** class defines the static **Projects** property as a +list of all created projects. The default constructor for the class adds the +new instance to the list of projects. + +```powershell +class ExampleProject6 { + [string] $Name + [int] $Size + [bool] $Completed + [string] $Assignee + [datetime] $StartDate + [datetime] $EndDate + [datetime] $DueDate + hidden [string] $Guid = (New-Guid).Guid + static [ExampleProject6[]] $Projects = @() + + ExampleProject6() { + [ExampleProject6]::Projects += $this + } +} + +"Project Count: $([ExampleProject6]::Projects.Count)" + +$project1 = [ExampleProject6]@{ Name = 'Project_1' } +$project2 = [ExampleProject6]@{ Name = 'Project_2' } + +[ExampleProject6]::Projects | Select-Object -Property Name, Guid +``` + +```Output +Project Count: 0 + +Name Guid +---- ---- +Project_1 75e7c8a0-f8d1-433a-a5be-fd7249494694 +Project_2 6c501be4-e68c-4df5-8fce-e49dd8366afe +``` + +### Example 7 - Defining a property in the constructor + +The **ExampleProject7** class defines the **Duration** script property in the +static class constructor with the `Update-TypeData` cmdlet. Using the +`Update-TypeData` or `Add-Member` cmdlet is the only way to define advanced +properties for PowerShell classes. + +The **Duration** property returns a value of `$null` unless both the +**StartDate** and **EndDate** properties are set and **StartDate** is defined +to be earlier than the **EndDate**. + +```powershell +class ExampleProject7 { + [string] $Name + [int] $Size + [bool] $Completed + [string] $Assignee + [datetime] $StartDate + [datetime] $EndDate + [datetime] $DueDate + + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberName = 'Duration' + MemberType = 'ScriptProperty' + Value = { + [datetime]$UnsetDate = 0 + + $StartNotSet = $this.StartDate -eq $UnsetDate + $EndNotSet = $this.EndDate -eq $UnsetDate + $StartAfterEnd = $this.StartDate -gt $this.EndDate + + if ($StartNotSet -or $EndNotSet -or $StartAfterEnd) { + return $null + } + + return $this.EndDate - $this.StartDate + } + } + ) + + static ExampleProject7() { + $TypeName = [ExampleProject7].Name + foreach ($Definition in [ExampleProject7]::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } + + ExampleProject7() {} + + ExampleProject7([string]$Name) { + $this.Name = $Name + } +} + +$Project = [ExampleProject7]::new() +$Project + +$null -eq $Project.Duration +``` + +```Output +Duration : +Name : +Size : 0 +Completed : False +Assignee : +StartDate : 1/1/0001 12:00:00 AM +EndDate : 1/1/0001 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM + +True +``` + +The default view for an instance of the **ExampleProject7** class includes the +duration. Because the **StartDate** and **EndDate** properties aren't set, the +**Duration** property is `$null`. + +```powershell +$Project.StartDate = '2023-01-01' +$Project.EndDate = '2023-01-08' + +$Project +``` + +```Output +Duration : 7.00:00:00 +Name : +Size : 0 +Completed : False +Assignee : +StartDate : 1/1/2023 12:00:00 AM +EndDate : 1/8/2023 12:00:00 AM +DueDate : 1/1/0001 12:00:00 AM +``` + +With the properties set correctly, the **Duration** property returns a timespan +representing how long the project ran. + +## Default property values + +Every class property has an implicit default value depending on the type of the +property. + +If a property is a [reference type][04], like a string or an object, the +implicit default value is `$null`. If a property is a [value type][05], like a +number, boolean, or enumeration, the property has a default value depending on +the type: + +- Numeric types, like integers and floating-point numbers, default to `0` +- Boolean values default to `$false` +- Enumerations default to `0`, even the enumeration doesn't define a label for + `0`. + +For more information about default values in .NET, see +[Default values of C# types (C# reference)][06]. + +To define an explicit default value for a property, declare the property with +an assignment to the default value. + +For example, this definition for the **ProjectTask** class defines an explicit +default value for the **Guid** property, assigning a random GUID to each new +instance. + +```powershell +class ProjectTask { + [string] $Name + [string] $Description + [string] $Guid = (New-Guid).Guid +} + +[ProjectTask]::new() +``` + +```Output +Name Description Guid +---- ----------- ---- + aa96350c-358d-465c-96d1-a49949219eec +``` + +Hidden and static properties can also have default values. + +## Hidden properties + +You can hide properties of a class by declaring them with the `hidden` keyword. +Hidden class properties are: + +- Not included in the default output for the class. +- Not included in the list of class members returned by the `Get-Member` + cmdlet. To show hidden properties with `Get-Member`, use the **Force** + parameter. +- Not displayed in tab completion or IntelliSense unless the completion occurs + in the class that defines the hidden property. +- Public members of the class. They can be accessed and modified. Hiding a + property doesn't make it private. It only hides the property as described in + the previous points. + +For more information about the `hidden` keyword, see [about_Hidden][07]. + +## Static properties + +You can define a property as belonging to the class itself instead of instances +of the class by declaring the property with the `static` keyword. Static class +properties: + +- Are always available, independent of class instantiation. +- Are shared across all instances of the class. +- Are always available. +- Are modifiable. Static properties can be updated. They aren't immutable by + default. +- Live for the entire session span. + +> [!IMPORTANT] +> Static properties for classes defined in PowerShell aren't immutable. They +> can + +## Derived class properties + +When a class derives from a base class, it inherits the properties of the base +class. Any properties defined on the base class, including hidden properties, +are available on the derived class. + +A derived class can override an inherited property by redefining it in the +class definition. The property on the derived class uses the redefined type and +default value, if any. If the inherited property defined a default value and +the redefined property doesn't, the inherited property has no default value. + +If a derived class doesn't override a static property, accessing the static +property through the derived class accesses the static property of the base +class. Modifying the property value through the derived class modifies the +value on the base class. Any other derived class that doesn't override the +static property also uses the value of the property on the base class. Updating +the value of an inherited static property in a class that doesn't override the +property might have unintended effects for classes derived from the same base +class. + +The following example shows the behavior for static and instance properties on +derived classes. + +```powershell +class BaseClass { + static [string] $StaticProperty = 'Static' + [string] $InstanceProperty = 'Instance' +} +class DerivedClassA : BaseClass {} +class DerivedClassB : BaseClass {} +class DerivedClassC : DerivedClassB { + [string] $InstanceProperty +} +class DerivedClassD : BaseClass { + static [string] $StaticProperty = 'Override' + [string] $InstanceProperty = 'Override' +} + +"Base instance => $([BaseClass]::new().InstanceProperty)" +"Derived instance A => $([DerivedClassA]::new().InstanceProperty)" +"Derived instance B => $([DerivedClassB]::new().InstanceProperty)" +"Derived instance C => $([DerivedClassC]::new().InstanceProperty)" +"Derived instance D => $([DerivedClassD]::new().InstanceProperty)" +``` + +```Output +Base instance => Instance +Derived instance A => Instance +Derived instance B => Instance +Derived instance C => +Derived instance D => Override +``` + +The **InstanceProperty** for **DerivedClassC** is an empty string because the +class redefined the property without setting a default value. For +**DerivedClassD** the value is `Override` because the class redefined the +property with that string as the default value. + +```powershell +"Base static => $([BaseClass]::StaticProperty)" +"Derived static A => $([DerivedClassA]::StaticProperty)" +"Derived static B => $([DerivedClassB]::StaticProperty)" +"Derived static C => $([DerivedClassC]::StaticProperty)" +"Derived static D => $([DerivedClassD]::StaticProperty)" +``` + +```Output +Base static => Static +Derived static A => Static +Derived static B => Static +Derived static C => Static +Derived static D => Override +``` + +Except for **DerivedClassD**, the value of the static property for the derived +classes is the same as the base class, because they don't redefine the +property. This applies even to **DerivedClassC**, which inherits from +**DerivedClassB** instead of directly from **BaseClass**. + +```powershell +[DerivedClassA]::StaticProperty = 'Updated from A' +"Base static => $([BaseClass]::StaticProperty)" +"Derived static A => $([DerivedClassA]::StaticProperty)" +"Derived static B => $([DerivedClassB]::StaticProperty)" +"Derived static C => $([DerivedClassC]::StaticProperty)" +"Derived static D => $([DerivedClassD]::StaticProperty)" +``` + +```Output +Base static => Updated from A +Derived static A => Updated from A +Derived static B => Updated from A +Derived static C => Updated from A +Derived static D => Override +``` + +When **StaticProperty** is accessed and modified through **DerivedClassA**, the +changed value affects every class except for **DerivedClassD**. + +For more information about class inheritance, including a comprehensive +example, see [about_Classes_Inheritance][08]. + +## Using property attributes + +PowerShell includes several attribute classes that you can use to enhance data +type information and validate the data assigned to a property. Validation +attributes allow you to test that values given to properties meet defined +requirements. Validation is triggered the moment that the value is assigned. + +For more information on available attributes, see +[about_Functions_Advanced_Parameters][09]. + +## Defining instance properties with Update-TypeData + +Beyond declaring properties directly in the class definition, you can define +properties for instances of a class in the static constructor using the +`Update-TypeData` cmdlet. + +Use this snippet as a starting point for the pattern. Replace the placeholder +text in angle brackets as needed. + +```powershell +class { + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberName = '' + MemberType = '' + Value = + } + ) + + static () { + $TypeName = [].Name + foreach ($Definition in []::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } +} +``` + +> [!TIP] +> The `Add-Member` cmdlet can add properties and methods to a class in +> non-static constructors, but the cmdlet is run every time the constructor +> is called. Using `Update-TypeData` in the static constructor ensures that the +> code for adding the members to the class only needs to run once in a session. +> +> Only add properties to the class in non-static constructors when they can't +> be defined with `Update-TypeData`, like read-only properties. + +### Defining alias properties + +The **Alias** attribute has no effect when used on a class property +declaration. PowerShell only uses that attribute to define aliases for cmdlet, +parameter, and function names. + +To define an alias for a class property, use `Update-TypeData` with the +`AliasProperty` **MemberType**. + +For example, this definition of the **OperablePair** class defines two integer +properties **x** and **y** with the aliases **LeftHandSide** and +**RightHandSide** respectively. + +```powershell +class OperablePair { + [int] $x + [int] $y + + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberType = 'AliasProperty' + MemberName = 'LeftHandSide' + Value = 'x' + } + @{ + MemberType = 'AliasProperty' + MemberName = 'RightHandSide' + Value = 'y' + } + ) + + static OperablePair() { + $TypeName = [OperablePair].Name + foreach ($Definition in [OperablePair]::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } + + OperablePair() {} + + OperablePair([int]$x, [int]$y) { + $this.x = $x + $this.y = $y + } + + # Math methods for the pair of values + [int] GetSum() { return $this.x + $this.y } + [int] GetProduct() { return $this.x * $this.y } + [int] GetDifference() { return $this.x - $this.y } + [float] GetQuotient() { return $this.x / $this.y } + [int] GetModulus() { return $this.x % $this.y } +} +``` + +With the aliases defined, users can access the properties with either name. + +```powershell +$pair = [OperablePair]@{ x = 8 ; RightHandSide = 3 } + +"$($pair.x) % $($pair.y) = $($pair.GetModulus())" + +$pair.LeftHandSide = 3 +$pair.RightHandSide = 2 +"$($pair.x) x $($pair.y) = $($pair.GetProduct())" +``` + +```Output +8 % 3 = 2 + +3 x 2 = 6 +``` + +### Defining calculated properties + +To define a property that references the values of other properties, use the +`Update-TypeData` cmdlet with the `ScriptProperty` **MemberType**. + +For example, this definition of the **Budget** class defines the **Expenses** +and **Revenues** properties as arrays of floating-point numbers. It uses the +`Update-TypeData` cmdlet to define calculated properties for total expenses, +total revenues, and net income. + +```powershell +class Budget { + [float[]] $Expenses + [float[]] $Revenues + + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberType = 'ScriptProperty' + MemberName = 'TotalExpenses' + Value = { ($this.Expenses | Measure-Object -Sum).Sum } + } + @{ + MemberType = 'ScriptProperty' + MemberName = 'TotalRevenues' + Value = { ($this.Revenues | Measure-Object -Sum).Sum } + } + @{ + MemberType = 'ScriptProperty' + MemberName = 'NetIncome' + Value = { $this.TotalRevenues - $this.TotalExpenses } + } + ) + + static Budget() { + $TypeName = [Budget].Name + foreach ($Definition in [Budget]::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } + + Budget() {} + + Budget($Expenses, $Revenues) { + $this.Expenses = $Expenses + $this.Revenues = $Revenues + } +} + +[Budget]::new() + +[Budget]@{ + Expenses = @(2500, 1931, 3700) + Revenues = @(2400, 2100, 4150) +} +``` + +```Output +TotalExpenses : 0 +TotalRevenues : 0 +NetIncome : 0 +Expenses : +Revenues : + +TotalExpenses : 8131 +TotalRevenues : 8650 +NetIncome : 519 +Expenses : {2500, 1931, 3700} +Revenues : {2400, 2100, 4150} +``` + +### Defining properties with custom get and set logic + +PowerShell class properties can't define custom getter and setter logic +directly. You can approximate this functionality by defining a backing property +with the `hidden` keyword and using `Update-TypeData` to define a visible +property with custom logic for getting and setting the value. + +By convention, define the hidden backing property name with an underscore +prefix and use camel casing. For example, instead of `TaskCount`, name the +hidden backing property `_taskCount`. + +In this example, the **ProjectSize** class defines a hidden integer property +named **_value**. It defines **Value** as a `ScriptProperty` with custom logic +for getting and setting the **_value** property. The setter scriptblock handles +converting the string representation of the project to the correct size. + +```powershell +class ProjectSize { + hidden [ValidateSet(0, 1, 2, 3)] [int] $_value + + static [hashtable[]] $MemberDefinitions = @( + @{ + MemberType = 'ScriptProperty' + MemberName = 'Value' + Value = { $this._value } # Getter + SecondValue = { # Setter + $ProposedValue = $args[0] + + if ($ProposedValue -is [string]) { + switch ($ProposedValue) { + 'Small' { $this._value = 1 ; break } + 'Medium' { $this._value = 2 ; break } + 'Large' { $this._value = 3 ; break } + default { throw "Unknown size '$ProposedValue'" } + } + } else { + $this._value = $ProposedValue + } + } + } + ) + + static ProjectSize() { + $TypeName = [ProjectSize].Name + foreach ($Definition in [ProjectSize]::MemberDefinitions) { + Update-TypeData -TypeName $TypeName @Definition + } + } + + ProjectSize() {} + ProjectSize([int]$Size) { $this.Value = $Size } + ProjectSize([string]$Size) { $this.Value = $Size } + + [string] ToString() { + $Output = switch ($this._value) { + 1 { 'Small' } + 2 { 'Medium' } + 3 { 'Large' } + default { 'Undefined' } + } + + return $Output + } +} +``` + +With the custom getter and setter defined, you can set the **Value** property +as either an integer or string. + +```powershell +$size = [ProjectSize]::new() +"The initial size is: $($size._value), $size" + +$size.Value = 1 +"The defined size is: $($size._value), $size" + +$Size.Value += 1 +"The updated size is: $($size._value), $size" + +$Size.Value = 'Large' +"The final size is: $($size._value), $size" +``` + +```Output +The initial size is: 0, Undefined + +The defined size is: 1, Small + +The updated size is: 2, Medium + +The final size is: 3, Large +``` + +## Limitations + +PowerShell class properties have the following limitations: + +- Static properties are always mutable. PowerShell classes can't define + immutable static properties. + + Workaround: None. +- Properties can't use the **ValidateScript** attribute, because class property + attribute arguments must be constants. + + Workaround: Define a class that inherits from the + **ValidateArgumentsAttribute** type and use that attribute instead. +- Directly declared properties can't define custom getter and setter + implementations. + + Workaround: Define a hidden property and use `Update-TypeData` to define the + visible getter and setter logic. +- Properties can't use the **Alias** attribute. The attribute only applies to + parameters, cmdlets, and functions. + + Workaround: Use the `Update-TypeData` cmdlet to define aliases in the class + constructors. +- When a PowerShell class is converted to JSON with the `ConvertTo-Json` + cmdlet, the output JSON includes all hidden properties and their values. + + Workaround: None + +## See also + +- [about_Classes][10] +- [about_Classes_Constructors][11] +- [about_Classes_Inheritance][12] +- [about_Classes_Methods][13] + +[01]: #hidden-properties +[02]: #static-properties +[03]: #default-property-values +[04]: /dotnet/csharp/language-reference/keywords/reference-types +[05]: /dotnet/csharp/language-reference/builtin-types/value-types +[06]: /dotnet/csharp/language-reference/builtin-types/default-values +[07]: about_Hidden.md +[08]: about_Classes_Inheritance.md +[09]: about_functions_advanced_parameters.md#parameter-and-variable-validation-attributes +[10]: about_Classes.md +[11]: about_Classes_Constructors.md +[12]: about_Classes_Inheritance.md +[13]: about_Classes_Methods.md diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Command_Precedence.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Command_Precedence.md new file mode 100644 index 000000000000..34d598d0d0f4 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Command_Precedence.md @@ -0,0 +1,343 @@ +--- +description: Describes how PowerShell determines which command to run. +Locale: en-US +ms.date: 03/05/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_command_precedence?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Command_Precedence +--- +# about_Command_Precedence + +## Short description + +Describes how PowerShell determines which command to run. + +## Long description + +Command precedence describes how PowerShell determines which command to run +when a session contains more than one command with the same name. Commands +within a session can be hidden or replaced by commands with the same name. This +article shows you how to run hidden commands and how to avoid command-name +conflicts. + +## Command precedence + +When a PowerShell session includes more than one command that has the same +name, PowerShell determines which command to run using the following rules. + +If you specify the path to a command, PowerShell runs the command at the +location specified by the path. + +For example, the following command runs the FindDocs.ps1 script in the +`C:\TechDocs` directory: + +```powershell +C:\TechDocs\FindDocs.ps1 +``` + +You can run any executable command using its full path. As a security feature, +PowerShell doesn't run executable commands, including PowerShell scripts and +native commands, unless the command is located in a path listed in the +`$env:Path` environment variable. + +To run an executable file that's in the current directory, specify the full +path or use the relative path `.\` to represent the current directory. + +For example, to run the `FindDocs.ps1` file in the current directory, type: + +```powershell +.\FindDocs.ps1 +``` + +If you don't specify a path, PowerShell uses the following precedence order +when it runs commands. + +1. Alias +1. Function +1. Cmdlet (see [Cmdlet name resolution][05]) +1. External executable files (including PowerShell script files) + +Therefore, if you type `help`, PowerShell first looks for an alias named +`help`, then a function named `Help`, and finally a cmdlet named `Help`. It +runs the first `help` item that it finds. + +For example, if your session contains a cmdlet and a function, both named +`Get-Map`, when you type `Get-Map`, PowerShell runs the function. + +> [!NOTE] +> This only applies to loaded commands. If there is a `build` executable and an +> Alias `build` for a function with the name of `Invoke-Build` inside a module +> that is not loaded into the current session, PowerShell runs the `build` +> executable instead. It doesn't auto-load modules if it finds the external +> executable. It's only when no external executable is found that an alias, +> function, or cmdlet with the given name is invoked. + +## Resolving items with the same names + +As a result of these rules, items can be replaced or hidden by items with the +same name. + +Items are _hidden_ or _shadowed_ if you can still access the original item, +such as by qualifying the item name with a module name. + +For example, if you import a function that has the same name as a cmdlet in the +session, the cmdlet is _hidden_, but not replaced. You can run the cmdlet by +specifying its module-qualified name. + +When items are _replaced_ or _overwritten_, you can no longer access the +original item. + +For example, if you import a variable that has the same name as a variable in +the session, the original variable is replaced. You can't qualify a variable +with a module name. + +If you create a function at the command line and then import a function with +the same name, the original function is replaced. + +## Finding hidden commands + +The **All** parameter of the [Get-Command][10] cmdlet gets all commands with +the specified name, even if they're hidden or replaced. Beginning in PowerShell +3.0, by default, `Get-Command` gets only the commands that run when you type +the command name. + +In the following examples, the session includes a `Get-Date` function and a +[Get-Date][14] cmdlet. You can use `Get-Command` to determine which command is +chosen first. + +```powershell +Get-Command Get-Date +``` + +```Output +CommandType Name ModuleName +----------- ---- ---------- +Function Get-Date +``` + +Uses the **All** parameter to list available `Get-Date` commands. + +```powershell +Get-Command Get-Date -All +``` + +```Output +CommandType Name Version Source +----------- ---- ------- ------ +Function Get-Date +Cmdlet Get-Date 7.0.0.0 Microsoft.PowerShell.Utility +``` + +```powershell +Get-Command where -All +``` + +```Output +CommandType Name Version Source +----------- ---- ------- ------ +Alias where -> Where-Object +Application where.exe 10.0.22621.1 C:\Windows\system32\where.exe +``` + +You can run particular commands by including qualifying information that +distinguishes the command from other commands that might have the same name. +For cmdlets, you can use the module-qualified name. For executables, you can +include the file extension. For example, to run the executable version of +`where` use `where.exe`. + +### Use module-qualified names + +Using the module-qualified name of a cmdlet allows you to run commands hidden +by an item with the same name. For example, you can run the `Get-Date` cmdlet +by qualifying it with its module name **Microsoft.PowerShell.Utility** or its +path. When you use module-qualified names, the module can be automatically +imported into the session depending on the value of +[`$PSModuleAutoLoadingPreference`][03]. + +> [!NOTE] +> You can't use module names to qualify variables or aliases. + +Using module-qualified names ensures that you are running the command that you +intend to run. This is the recommended method of calling cmdlets when writing +scripts that you intend to distribute. + +The following example illustrates how to qualify a command by including its +module name. + +> [!IMPORTANT] +> Module qualification uses the backslash character (`\`) to separate the +> module name from the command name, regardless of the platform. + +```powershell +New-Alias -Name "Get-Date" -Value "Get-ChildItem" +Microsoft.PowerShell.Utility\Get-Date +``` + +```Output +Tuesday, May 16, 2023 1:32:51 PM +``` + +To run a `New-Map` command from the `MapFunctions` module, use its +module-qualified name: + +```powershell +MapFunctions\New-Map +``` + +To find the module from which a command was imported, use the **ModuleName** +property of commands. + +``` +(Get-Command ).ModuleName +``` + +For example, to find the source of the `Get-Date` cmdlet, type: + +```powershell +(Get-Command Get-Date).ModuleName +``` + +```Output +Microsoft.PowerShell.Utility +``` + +If you want to qualify the name of the command using the path to the module, +you must use the forward slash (`/`) as the path separator and the backslash +character (`\`) before the command name. Use the following example to run the +`Get-Date` cmdlet: + +```powershell +//localhost/c$/Progra~1/PowerShell/7-preview/Modules/Microsoft.PowerShell.Utility\Get-Date +``` + +The path can be a full path or a path that is relative to the current location. +On Windows, you can't use a drive-qualified path. You must use a UNC path, as +shown in the previous example, or a path that's relative to the current drive. +The following example assumes that your current location is in the `C:` drive. + +```powershell +/Progra~1/PowerShell/7-preview/Modules/Microsoft.PowerShell.Utility\Get-Date +``` + +### Use the call operator + +You can also use the call operator (`&`) to run hidden commands by combining it +with a call to [Get-ChildItem][13] (the alias is `dir`), `Get-Command` or +[Get-Module][11]. + +The call operator executes strings and script blocks in a child scope. For more +information, see [about_Operators][08]. + +For example, use the following command to run the function named `Map` that's +hidden by an alias named `Map`. + +```powershell +& (Get-Command -Name Map -CommandType Function) +``` + +or + +```powershell +& (dir Function:\map) +``` + +You can also save your hidden command in a variable to make it easier to run. + +For example, the following command saves the `Map` function in the `$myMap` +variable and then uses the `Call` operator to run it. + +```powershell +$myMap = (Get-Command -Name map -CommandType function) +& ($myMap) +``` + +## Replaced items + +A _replaced_ item is one that you can no longer access. You can replace items +by importing items of the same name from a module. + +For example, if you type a `Get-Map` function in your session, and you import a +function called `Get-Map`, it replaces the original function. You can't +retrieve it in the current session. + +Variables and aliases can't be hidden because you can't use a call operator or +a qualified name to run them. When you import variables and aliases from a +module, they replace variables in the session with the same name. + +## Cmdlet name resolution + +When you don't use the qualified name of a cmdlet, PowerShell checks to see if +the cmdlet is loaded in the current session. If there are multiple modules +loaded that contain the same cmdlet name, PowerShell uses the cmdlet from the +first module found alphabetically. + +If the cmdlet isn't loaded, PowerShell searches the installed modules and +autoloads the first module that contains the cmdlet and runs that cmdlet. +PowerShell searches for modules in each path defined in the `$env:PSModulePath` +environment variable. The paths are searched in the order that they're listed +in the variable. Within each path, the modules are searched in alphabetical +order. PowerShell uses the cmdlet from the first match it finds. + +## Avoiding name conflicts + +The best way to manage command name conflicts is to prevent them. When you name +your commands, use a unique name. For example, add your initials or company +name acronym to the nouns in your commands. + +When you import commands into your session from a PowerShell module or from +another session, you can use the `Prefix` parameter of the [Import-Module][12] +or [Import-PSSession][15] cmdlet to add a prefix to the nouns in the names of +commands. + +For example, the following command avoids any conflict with the `Get-Date` and +`Set-Date` cmdlets that come with PowerShell when you import the +`DateFunctions` module. + +```powershell +Import-Module -Name DateFunctions -Prefix ZZ +``` + +## Running external executables + +On Windows. PowerShell treats the file extensions listed in the `$env:PATHEXT` +environment variable as executable files. Files that aren't Windows executables +are handed to Windows to process. Windows looks up the file association and +executes the default Windows Shell verb for the extension. For Windows to +support the execution by file extension, the association must be registered +with the system. + +You can register the executable engine for a file extension using the `ftype` +and `assoc` commands of the CMD command shell. PowerShell has no direct method +to register the file handler. For more information, see the documentation for +the [ftype][04] command. + +For PowerShell to see a file extension as executable in the current session, +you must add the extension to the `$env:PATHEXT` environment variable. + +## See also + +- [about_Aliases][06] +- [about_Functions][07] +- [about_Path_Syntax][09] +- [Alias-Provider][01] +- [Function-Provider][02] +- [Get-Command][10] +- [Import-Module][12] +- [Import-PSSession][15] + + +[01]: ./about_Alias_Provider.md +[02]: ./about_Function_Provider.md +[03]: ./about_preference_variables.md#psmoduleautoloadingpreference +[04]: /windows-server/administration/windows-commands/ftype +[05]: #cmdlet-name-resolution +[06]: about_Aliases.md +[07]: about_Functions.md +[08]: about_Operators.md +[09]: about_Path_Syntax.md +[10]: xref:Microsoft.PowerShell.Core.Get-Command +[11]: xref:Microsoft.PowerShell.Core.Get-Module +[12]: xref:Microsoft.PowerShell.Core.Import-Module +[13]: xref:Microsoft.PowerShell.Management.Get-ChildItem +[14]: xref:Microsoft.PowerShell.Utility.Get-Date +[15]: xref:Microsoft.PowerShell.Utility.Import-PSSession diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Command_Syntax.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Command_Syntax.md new file mode 100644 index 000000000000..1cfa585dc624 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Command_Syntax.md @@ -0,0 +1,278 @@ +--- +description: Describes the syntax diagrams that are used in PowerShell. +Locale: en-US +ms.date: 10/31/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_command_syntax?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Command_Syntax +--- +# about_Command_Syntax + +## Short description + +Describes the syntax diagrams that are used in PowerShell. + +## Long description + +The [Get-Help][03] and [Get-Command][02] cmdlets display syntax diagrams to +help you construct commands correctly. This article explains how to interpret +the syntax diagrams. + +## Get the syntax for a command + +There are two ways to get the syntax for a command: `Get-Help` and +`Get-Command`. + +### Get-Command + +The `Get-Command` command can be used to get information about any command on +your system. Use the **Syntax** parameter to get the syntax for a command. + +```powershell +Get-Command Get-Command -Syntax +``` + +```Output +Get-Command [[-ArgumentList] ] [-Verb ] [-Noun ] + [-Module ] [-FullyQualifiedModule ] + [-TotalCount ] [-Syntax] [-ShowCommandInfo] [-All] [-ListImported] + [-ParameterName ] [-ParameterType ] + [] + +Get-Command [[-Name] ] [[-ArgumentList] ] + [-Module ] [-FullyQualifiedModule ] + [-CommandType ] [-TotalCount ] [-Syntax] [-ShowCommandInfo] + [-All] [-ListImported] [-ParameterName ] + [-ParameterType ] [-UseFuzzyMatching] + [-FuzzyMinimumDistance ] [-UseAbbreviationExpansion] + [] +``` + +### Get-Help + +The `Get-Help` command provides detailed information about PowerShell commands +including, syntax, detailed description of the cmdlet and parameters, and +examples. The output `Get-Help` command starts with a brief description of the +command followed by the syntax. + +```powershell +Get-Help Get-Command +``` + +The following output has been shortened to focus on the syntax description. + +```Output +NAME + Get-Command + +SYNOPSIS + Gets all commands. + +SYNTAX + + Get-Command [[-Name] ] [[-ArgumentList] ] + [-All] [-CommandType {Alias | Function | Filter | Cmdlet | ExternalScript | + Application | Script | Workflow | Configuration | All}] + [-FullyQualifiedModule ] + [-ListImported] [-Module ] [-ParameterName ] + [-ParameterType ] + [-ShowCommandInfo] [-Syntax] [-TotalCount ] + [-UseAbbreviationExpansion] [-UseFuzzyMatching] [] + + Get-Command [[-ArgumentList] ] [-All] + [-FullyQualifiedModule ] + [-ListImported] [-Module ] [-Noun ] + [-ParameterName ] + [-ParameterType ] + [-ShowCommandInfo] [-Syntax] [-TotalCount ] + [-Verb ] [] +... +``` + +The output of `Get-Help` is slightly different from the output of +`Get-Command`. Notice the difference in the syntax for the **CommandType** +parameter. `Get-Command` shows the parameter type as the `[CommandTypes]` +enumeration, while `Get-Help` show the possible values for the enumeration. + +## Parameter Sets + +The parameters of a PowerShell command are listed in parameter sets. A +PowerShell command can have one or more parameter sets. The `Get-Command` +cmdlet has two parameter sets, as shown in the previous examples. + +Some of the cmdlet parameters are unique to a parameter set, and others appear +in multiple parameter sets. Each parameter set represents the format for a +valid command. A parameter set includes only parameters that can be used +together in a command. When parameters can't be used in the same command, they +are listed in separate parameter sets. + +For example, the [Get-Random][05] cmdlet has the following parameter sets: + +```powershell +$cmd = Get-Command Get-Random +$cmd.ParameterSets | + Select-Object Name, IsDefault, @{n='Parameters';e={$_.ToString()}} | + Format-Table -Wrap +``` + +```Output +Name IsDefault Parameters +---- --------- ---------- +RandomNumberParameterSet True [[-Maximum] ] [-SetSeed ] + [-Minimum ] [-Count ] + [] +RandomListItemParameterSet False [-InputObject] [-SetSeed ] + [-Count ] [] +ShuffleParameterSet False [-InputObject] -Shuffle + [-SetSeed ] [] +``` + +- The first parameter set returns one or more random numbers and has the + **Minimum**, **Maximum**, and **Count** parameters. +- The second parameter set returns a randomly selected object from a set of + objects and includes the **InputObject** and **Count** parameters. +- The third parameter set has the **Shuffle** parameter that returns a + collection of objects in a random order, like shuffling a deck of cards. +- All parameter sets have the **SetSeed** parameter and the common parameters. + +These parameter sets show that you can use the **InputObject** and **Count** +parameters in the same command, but you can't use the **Maximum** and +**Shuffle** parameters together. + +Every cmdlet also has a default parameter set. The default parameter set is +used when you don't specify parameters that are unique to a parameter set. For +example, if you use `Get-Random` without parameters, PowerShell assumes that +you're using the **RandomNumberParameterSet** parameter set and it returns a +random number. + +## Symbols in Syntax Diagrams + +The syntax diagram lists the command name, the command parameters, and the +parameter values. + +The syntax diagrams use the following symbols: + +- A hyphen `-` indicates a parameter name. In a command, type the hyphen + immediately before the parameter name with no intervening spaces, as shown in + the syntax diagram. + + For example, to use the **Name** parameter of `Get-Command`, type: + `Get-Command -Name`. + + +- Angle brackets `< >` indicate placeholder text. You don't type the angle + brackets or the placeholder text in a command. Instead, you replace it with + the item that it describes. + + The placeholder inside the angle brackets identifies the .NET type of the + value that a parameter takes. For example, to use the **Name** parameter of + the `Get-Command` cmdlet, you replace the `` with one or more + strings separated by commas (`,`). + + +- Brackets `[]` appended to a .NET type indicate that the parameter can accept + one or more values of that type. Enter the values as a comma-separated + list. + + For example, the **Name** and **Value** parameters of the `New-Alias` cmdlet + only take one string each. + + ```Syntax + New-Alias [-Name] [-Value] + ``` + + ```powershell + New-Alias -Name MyAlias -Value mycommand.exe + ``` + + But the **Name** parameter of [Get-Process][04] can take one or more strings. + + ```Syntax + Get-Process [-Name] + ``` + + ```powershell + Get-Process -Name Explorer, Winlogon, Services + ``` + +- Parameters with no values + + Some parameters don't accept input, so they don't have a parameter value. + Parameters without values are _switch parameters_. Switch parameters are used + like boolean values. They default to `$false`. When you use a switch + parameter, the value is set to `$true`. + + For example, the **ListImported** parameter of `Get-Command` is a switch + parameter. When you use the **ListImported** parameter, the cmdlet return + only commands that were imported from modules in the current session. + + ```Syntax + Get-Command [-ListImported] + ``` + + +- Brackets `[ ]` around parameters indicate optional items. A parameter and + its value can be optional. For example, the **CommandType** parameter of + `Get-Command` and its value are enclosed in brackets because they're both + optional. + + ```Syntax + Get-Command [-CommandType ] + ``` + + Brackets around the parameter name, but not the parameter value, indicate + that the parameter name is optional. These parameters are known as positional + parameters. The parameter values must be presented in the correct order for + the values to be bound to the correct parameter. + + For example, for the `New-Alias` cmdlet, the **Name** and **Value** parameter + values are required, but the parameter names, `-Name` and `-Value`, are + optional. + + ```Syntax + New-Alias [-Name] [-Value] + ``` + + ```powershell + New-Alias MyAlias mycommand.exe + ``` + + In each parameter set, the parameters appear in position order. The order of + parameters in a command matters only when you omit the optional parameter + names. When parameter names are omitted, PowerShell assigns values to + parameters by position and type. For more information about parameter + position, see [about_Parameters][01]. + +- Braces `{}` indicate an "enumeration," which is a set of valid values for a + parameter. + + The values in the braces are separated by vertical bars `|`. These bars + indicate an _exclusive-OR_ choice, meaning that you can choose only one value + from the set of values that are listed inside the braces. + + For example, the syntax for the `New-Alias` cmdlet includes the following + value enumeration for the **Option** parameter: + + ```Syntax + New-Alias -Option {None | ReadOnly | Constant | Private | AllScope} + ``` + + The braces and vertical bars indicate that you can choose any one of the + listed values for the **Option** parameter, such as `ReadOnly` or `AllScope`. + + ```powershell + New-Alias -Option ReadOnly + ``` + +## See also + +- [about_Parameters][01] +- [Get-Command][02] +- [Get-Help][03] + + +[01]: about_Parameters.md +[02]: xref:Microsoft.PowerShell.Core.Get-Command +[03]: xref:Microsoft.PowerShell.Core.Get-Help +[04]: xref:Microsoft.PowerShell.Management.Get-Process +[05]: xref:Microsoft.PowerShell.Utility.Get-Random diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Comment_Based_Help.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Comment_Based_Help.md new file mode 100644 index 000000000000..8bc9cb055ab5 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Comment_Based_Help.md @@ -0,0 +1,858 @@ +--- +description: Describes how to write comment-based help content for functions and scripts. +Locale: en-US +ms.date: 01/09/2025 +no-loc: [.SYNOPSIS, .DESCRIPTION, .PARAMETER, .EXAMPLE, .INPUTS, .OUTPUTS, .NOTES, .LINK, .COMPONENT, .ROLE, .FUNCTIONALITY, .FORWARDHELPTARGETNAME, .FORWARDHELPCATEGORY, .REMOTEHELPRUNSPACE, .EXTERNALHELP] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comment_based_help?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Comment_Based_Help +--- +# about_Comment_Based_Help + +## Short description +Describes how to write comment-based help content for functions and scripts. + +## Long description + +You can write comment-based help content for functions and scripts by using +special help comment keywords. + +The [Get-Help][06] cmdlet displays comment-based help in the same format in +which it displays the cmdlet help content that are generated from XML files. +Users can use all of the parameters of `Get-Help`, such as **Detailed**, +**Full**, **Examples**, and **Online**, to display the contents of +comment-based help. + +You can also write XML-based help files for functions and scripts. To enable +the `Get-Help` cmdlet to find the XML-based help file for a function or script, +use the `.EXTERNALHELP` keyword. Without this keyword, `Get-Help` can't find +XML-based help content for functions or scripts. + +This topic explains how to write help content for functions and scripts. For +information about how to display help content for functions and scripts, see +[Get-Help][06]. + +The [Update-Help][08] and [Save-Help][07] cmdlets work only on XML files. +Updatable Help doesn't support comment-based help content. + +## Syntax for comment-based help + +To create Comment-based help content, you can use either style of comments: +single-line comments or block comments. + +The syntax for comment-based help is as follows: + +```Syntax +# . +# +``` + +or + +```Syntax +<# + . + +#> +``` + +Comment-based help is written as a series of comments. You can type a comment +symbol `#` before each line of comments, or you can use the `<#` and `#>` +symbols to create a comment block. All the lines within the comment block are +interpreted as comments. + +All of the lines in a comment-based help topic must be contiguous. If a +comment-based help topic follows a comment that's not part of the help topic, +there must be at least one blank line between the last non-help comment line +and the beginning of the comment-based help. + +Keywords define each section of comment-based help. Each comment-based help +keyword is preceded by a dot `.`. The keywords can appear in any order. The +keyword names aren't case-sensitive. + +For example, the `.Description` keyword precedes a description of a function or +script. + +```powershell +<# +.Description +Get-Function displays the name and syntax of all functions in the session. +#> +``` + +The comment block must contain at least one keyword. Some of the keywords, such +as `.EXAMPLE`, can appear many times in the same comment block. The help +content for each keyword begins on the line after the keyword and can span +multiple lines. + +## Syntax for comment-based help in functions + +Comment-based help for a function can appear in one of three locations: + +- At the beginning of the function body. +- At the end of the function body. +- Before the `function` keyword. There can't be more than one blank line + between the last line of the function help and the `function` keyword. + +For example: + +```powershell +function Get-Function { + <# + . + + #> + + # function logic +} +``` + +or + +```powershell +function Get-Function { + # function logic + + <# + . + + #> +} +``` + +or + +```powershell +<# + . + +#> +function Get-Function { } +``` + +## Syntax for comment-based help in scripts + +Comment-based help for a script can appear in one of the following two +locations in the script. + +- At the beginning of the script file. Script help can be preceded in the + script only by comments and blank lines. + + If the first item in the script body (after the help) is a function + declaration, there must be at least two blank lines between the end of the + script help and the function declaration. Otherwise, the help is interpreted + as being help for the function, not help for the script. + +- At the end of the script file. However, if the script is signed, place + Comment-based help at the beginning of the script file. The end of the script + is occupied by the signature block. + +For example: + +```powershell +<# +. + +#> +function Get-Function { } +``` + +or + +```powershell +function Get-Function { } +<# +. + +#> +``` + +## Comment-based help keywords + +The following are valid comment-based help keywords. These keywords can appear +in any order in the comment-based help, and they aren't case-sensitive. The +keywords are listed in in this article inthe order that they typically appear +in a help topic. + +### .SYNOPSIS + +A brief description of the function or script. This keyword can be used +only once in each topic. + +### .DESCRIPTION + +A detailed description of the function or script. This keyword can be +used only once in each topic. + +### .PARAMETER + +The description of a parameter. Add a `.PARAMETER` keyword for each parameter +in the function or script syntax. + +Type the parameter name on the same line as the `.PARAMETER` keyword. Type the +parameter description on the lines following the `.PARAMETER` keyword. Windows +PowerShell interprets all text between the `.PARAMETER` line and the next +keyword or the end of the comment block as part of the parameter description. +The description can include paragraph breaks. + +```Syntax +.PARAMETER +``` + +The Parameter keywords can appear in any order in the comment block, but the +function or script syntax determines the order in which the parameters (and +their descriptions) appear in help topic. To change the order, change the +syntax. + +You can also specify a parameter description by placing a comment in the +function or script syntax immediately before the parameter variable name. For +this to work, you must also have a comment block with at least one keyword. + +If you use both a syntax comment and a `.PARAMETER` keyword, the description +associated with the `.PARAMETER` keyword is used, and the syntax comment is +ignored. + +```powershell +<# +.SYNOPSIS + Short description here +#> +function Verb-Noun { + [CmdletBinding()] + param ( + # This is the same as .Parameter + [string]$Computername + ) + # Verb the Noun on the computer +} +``` + +### .EXAMPLE + +A sample command that uses the function or script, optionally followed by +sample output and a description. Repeat this keyword for each example. + +### .INPUTS + +The .NET types of objects that can be piped to the function or script. You can +also include a description of the input objects. + +### .OUTPUTS + +The .NET type of the objects that the cmdlet returns. You can also include a +description of the returned objects. + +### .NOTES + +Additional information about the function or script. + +### .LINK + +The name of a related topic. The value appears on the line below the ".LINK" +keyword and must be preceded by a comment symbol `#` or included in the +comment block. + +Repeat the `.LINK` keyword for each related topic. + +This content appears in the Related Links section of the help topic. + +The `.Link` keyword content can also include a Uniform Resource Identifier +(URI) to an online version of the same help topic. The online version opens +when you use the **Online** parameter of `Get-Help`. The URI must begin with +"http" or "https". + +### .COMPONENT + +The name of the technology or feature that the function or script uses, or to +which it's related. The **Component** parameter of `Get-Help` uses this value +to filter the search results returned by `Get-Help`. + +### .ROLE + +The name of the user role for the help topic. The **Role** parameter of +`Get-Help` uses this value to filter the search results returned by `Get-Help`. + +### .FUNCTIONALITY + +The keywords that describe the intended use of the function. The +**Functionality** parameter of `Get-Help` uses this value to filter the search +results returned by `Get-Help`. + +### .FORWARDHELPTARGETNAME + +Redirects to the help topic for the specified command. You can redirect users +to any help topic, including help content for a function, script, cmdlet, or +provider. + +```powershell +# .FORWARDHELPTARGETNAME +``` + +### .FORWARDHELPCATEGORY + +Specifies the help category of the item in `.ForwardHelpTargetName`. Valid +values are `Alias`, `Cmdlet`, `HelpFile`, `Function`, `Provider`, `General`, +`FAQ`, `Glossary`, `ScriptCommand`, `ExternalScript`, `Filter`, or `All`. Use +this keyword to avoid conflicts when there are commands with the same name. + +```powershell +# .FORWARDHELPCATEGORY +``` + +### .REMOTEHELPRUNSPACE + +Specifies a session that contains the help topic. Enter a variable that +contains a **PSSession** object. This keyword is used by the +[Export-PSSession][09] cmdlet to find the help content for the exported +commands. + +```powershell +# .REMOTEHELPRUNSPACE +``` + +### .EXTERNALHELP + +Specifies an XML-based help file for the script or function. + +```powershell +# .EXTERNALHELP +``` + +The `.EXTERNALHELP` keyword is required when a function or script is documented +in XML files. Without this keyword, `Get-Help` can't find the XML-based help +file for the function or script. + +The `.EXTERNALHELP` keyword takes precedence over other comment-based help +keywords. If `.EXTERNALHELP` is present, `Get-Help` doesn't display +comment-based help, even if it can't find a help topic that matches the value +of the `.EXTERNALHELP` keyword. + +If the function is exported by a module, set the value of the `.EXTERNALHELP` +keyword to a filename without a path. `Get-Help` looks for the specified file +name in a language-specific subdirectory of the module directory. There are no +requirements for the name of the XML-based help file for a function, but a best +practice is to use the following format: + +```Syntax +-help.xml +``` + +If the function isn't included in a module, include a path to the XML-based +help file. If the value includes a path and the path contains +UI-culture-specific subdirectories, `Get-Help` searches the subdirectories +recursively for an XML file with the name of the script or function in +accordance with the language fallback standards established for Windows, just +as it does in a module directory. + +For more information about the cmdlet help XML-based help file format, see +[How to Write Cmdlet Help][01]. + +## Autogenerated content + +The name, syntax, parameter list, parameter attribute table, common parameters, +and remarks are automatically generated by the `Get-Help` cmdlet. + +### Name + +The **Name** section of a function help topic is taken from the function name +in the function syntax. The **Name** of a script help topic is taken from the +script filename. To change the name or its capitalization, change the function +syntax or the script filename. + +### Syntax + +The **Syntax** section of the help topic is generated from the function or +script syntax. To add detail to the help topic syntax, such as the .NET type of +a parameter, add the detail to the syntax. If you don't specify a parameter +type, the **Object** type is inserted as the default value. + +### Parameter List + +The parameter list in the help topic is generated from the function or script +syntax and from the descriptions that you add by using the `.Parameter` +keyword. The function parameters appear in the **Parameters** section of the +help topic in the same order that they appear in the function or script syntax. +The spelling and capitalization of parameter names is also taken from the +syntax. It isn't affected by the parameter name specified by the `.Parameter` +keyword. + +### Common Parameters + +The **Common parameters** are added to the syntax and parameter list of the +help topic, even if they have no effect. For more information about the common +parameters, see [about_CommonParameters][02]. + +### Parameter Attribute Table + +`Get-Help` generates the table of parameter attributes that appears when you +use the **Full** or **Parameter** parameter of `Get-Help`. The value of the +**Required**, **Position**, and **Default** value attributes is taken from the +function or script syntax. + +Default values and a value for **Accept Wildcard characters** don't appear in +the parameter attribute table even when they're defined in the function or +script. To help users, provide this information in the parameter description. + +### Remarks + +The **Remarks** section of the help topic is automatically generated from the +function or script name. You can't change or affect its content. + +## Examples + +### Comment-based Help for a Function + +The following sample function includes comment-based help: + +```powershell +function Add-Extension +{ +param ([string]$Name,[string]$Extension = "txt") +$name = $name + "." + $extension +$name + +<# +.SYNOPSIS + +Adds a file name extension to a supplied name. + +.DESCRIPTION + +Adds a file name extension to a supplied name. +Takes any strings for the file name or extension. + +.PARAMETER Name +Specifies the file name. + +.PARAMETER Extension +Specifies the extension. "Txt" is the default. + +.INPUTS + +None. You can't pipe objects to Add-Extension. + +.OUTPUTS + +System.String. Add-Extension returns a string with the extension +or file name. + +.EXAMPLE + +PS> extension -name "File" +File.txt + +.EXAMPLE + +PS> extension -name "File" -extension "doc" +File.doc + +.EXAMPLE + +PS> extension "File" "doc" +File.doc + +.LINK + +http://www.fabrikam.com/extension.html + +.LINK + +Set-Item +#> +} +``` + +The results are as follows: + +```powershell +Get-Help -Name "Add-Extension" -Full +``` + +```Output +NAME + +Add-Extension + +SYNOPSIS + +Adds a file name extension to a supplied name. + +SYNTAX + +Add-Extension [[-Name] ] [[-Extension] ] +[] + +DESCRIPTION + +Adds a file name extension to a supplied name. Takes any strings for the +file name or extension. + +PARAMETERS + +-Name +Specifies the file name. + +Required? false +Position? 0 +Default value +Accept pipeline input? false +Accept wildcard characters? + +-Extension +Specifies the extension. "Txt" is the default. + +Required? false +Position? 1 +Default value +Accept pipeline input? false +Accept wildcard characters? + + +This cmdlet supports the common parameters: -Verbose, -Debug, +-ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable, +-OutBuffer and -OutVariable. For more information, type +"get-help about_commonparameters". + +INPUTS +None. You can't pipe objects to Add-Extension. + +OUTPUTS + +System.String. Add-Extension returns a string with the extension or +file name. + +Example 1 + +PS> extension -name "File" +File.txt + +Example 2 + +PS> extension -name "File" -extension "doc" +File.doc + +Example 3 + +PS> extension "File" "doc" +File.doc + +RELATED LINKS + +http://www.fabrikam.com/extension.html +Set-Item +``` + +### Parameter Descriptions in Function Syntax + +This example is the same as the previous one, except that the parameter +descriptions are inserted in the function syntax. This format is most useful +when the descriptions are brief. + +```powershell +function Add-Extension +{ +param +( + +[string] +#Specifies the file name. +$name, + +[string] +#Specifies the file name extension. "Txt" is the default. +$extension = "txt" +) + +$name = $name + "." + $extension +$name + +<# +.SYNOPSIS + +Adds a file name extension to a supplied name. + +.DESCRIPTION + +Adds a file name extension to a supplied name. Takes any strings for the +file name or extension. + +.INPUTS + +None. You can't pipe objects to Add-Extension. + +.OUTPUTS + +System.String. Add-Extension returns a string with the extension or +file name. + +.EXAMPLE + +PS> extension -name "File" +File.txt + +.EXAMPLE + +PS> extension -name "File" -extension "doc" +File.doc + +.EXAMPLE + +PS> extension "File" "doc" +File.doc + +.LINK + +http://www.fabrikam.com/extension.html + +.LINK + +Set-Item +#> +} +``` + +### Comment-based Help for a Script + +The following sample script includes comment-based help. Notice the blank lines +between the closing `#>` and the `Param` statement. In a script that doesn't +have a `Param` statement, there must be at least two blank lines between the +final comment in the help topic and the first function declaration. Without +these blank lines, `Get-Help` associates the help topic with the function, not +the script. + +```powershell +<# +.SYNOPSIS + +Performs monthly data updates. + +.DESCRIPTION + +The Update-Month.ps1 script updates the registry with new data generated +during the past month and generates a report. + +.PARAMETER InputPath +Specifies the path to the CSV-based input file. + +.PARAMETER OutputPath +Specifies the name and path for the CSV-based output file. By default, +MonthlyUpdates.ps1 generates a name from the date and time it runs, and +saves the output in the local directory. + +.INPUTS + +None. You can't pipe objects to Update-Month.ps1. + +.OUTPUTS + +None. Update-Month.ps1 doesn't generate any output. + +.EXAMPLE + +PS> .\Update-Month.ps1 + +.EXAMPLE + +PS> .\Update-Month.ps1 -inputpath C:\Data\January.csv + +.EXAMPLE + +PS> .\Update-Month.ps1 -inputpath C:\Data\January.csv -outputPath ` +C:\Reports\2009\January.csv +#> + +param ([string]$InputPath, [string]$OutPutPath) + +function Get-Data { } +... +``` + +The following command gets the script help. Because the script isn't in a +directory that's listed in the `$env:Path` environment variable, the +`Get-Help` command that gets the script help must specify the script path. + +```powershell +Get-Help -Name .\update-month.ps1 -Full +``` + +```Output +# NAME + +C:\ps-test\Update-Month.ps1 + +# SYNOPSIS + +Performs monthly data updates. + +# SYNTAX + +C:\ps-test\Update-Month.ps1 [-InputPath] [[-OutputPath] +] [] + +# DESCRIPTION + +The Update-Month.ps1 script updates the registry with new data +generated during the past month and generates a report. + +# PARAMETERS + +-InputPath +Specifies the path to the CSV-based input file. + +Required? true +Position? 0 +Default value +Accept pipeline input? false +Accept wildcard characters? + +-OutputPath +Specifies the name and path for the CSV-based output file. By +default, MonthlyUpdates.ps1 generates a name from the date +and time it runs, and saves the output in the local directory. + +Required? false +Position? 1 +Default value +Accept pipeline input? false +Accept wildcard characters? + + +This cmdlet supports the common parameters: -Verbose, -Debug, +-ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable, +-OutBuffer and -OutVariable. For more information, type, +"get-help about_commonparameters". + +# INPUTS + +None. You can't pipe objects to Update-Month.ps1. + +# OUTPUTS + +None. Update-Month.ps1 doesn't generate any output. + +Example 1 + +PS> .\Update-Month.ps1 + +Example 2 + +PS> .\Update-Month.ps1 -inputpath C:\Data\January.csv + +Example 3 + +PS> .\Update-Month.ps1 -inputpath C:\Data\January.csv -outputPath +C:\Reports\2009\January.csv + +# RELATED LINKS +``` + +### Redirecting to an XML File + +You can write XML-based help content for functions and scripts. Although +comment-based help is easier to implement, XML-based help is required for +Updatable Help and to provide help content in multiple languages. + +The following example shows the first few lines of the Update-Month.ps1 script. +The script uses the `.EXTERNALHELP` keyword to specify the path to an XML-based +help topic for the script. + +Note that the value of the `.EXTERNALHELP` keyword appears on the same line as +the keyword. Any other placement is ineffective. + +```powershell +# .EXTERNALHELP C:\MyScripts\Update-Month-Help.xml + +param ([string]$InputPath, [string]$OutPutPath) +function Get-Data { } +... +``` + +The following examples show three valid placements of the `.EXTERNALHELP` +keyword in a function. + +```powershell +function Add-Extension { + # .EXTERNALHELP C:\ps-test\Add-Extension.xml + + param ([string] $name, [string]$extension = "txt") + $name = $name + "." + $extension + $name +} +``` + +```powershell +function Add-Extension { + param ([string] $name, [string]$extension = "txt") + $name = $name + "." + $extension + $name + + # .EXTERNALHELP C:\ps-test\Add-Extension.xml +} +``` + +```powershell +# .EXTERNALHELP C:\ps-test\Add-Extension.xml +function Add-Extension { + param ([string] $name, [string]$extension = "txt") + $name = $name + "." + $extension + $name +} +``` + +### Redirecting to a Different Help Topic + +The following code is an excerpt from the beginning of the built-in help +function in PowerShell, which displays one screen of help text at a time. +Because the help topic for the `Get-Help` cmdlet describes the help function, +the help function uses the `.ForwardHelpTargetName` and `.ForwardHelpCategory` +keywords to redirect the user to the `Get-Help` cmdlet help topic. + +```powershell +function help { + <# + .FORWARDHELPTARGETNAME Get-Help + .FORWARDHELPCATEGORY Cmdlet + #> + + [CmdletBinding(DefaultParameterSetName='AllUsersView')] + param( + [Parameter(Position=0, ValueFromPipelineByPropertyName=$true)] + [System.String] + ${Name}, + ... +``` + +The following command uses this feature: + +```powershell +Get-Help -Name help +``` + +```Output +NAME + +Get-Help + +SYNOPSIS + +Displays information about PowerShell cmdlets and concepts. +... +``` + +## See also + +- [about_Functions][04] +- [about_Functions_Advanced_Parameters][03] +- [about_Scripts][05] +- [Writing Comment-Based help content][01] + + +[01]: /powershell/scripting/developer/help/writing-comment-based-help-topics +[02]: about_CommonParameters.md +[03]: about_Functions_Advanced_Parameters.md +[04]: about_Functions.md +[05]: about_Scripts.md +[06]: xref:Microsoft.PowerShell.Core.Get-Help +[07]: xref:Microsoft.PowerShell.Core.Save-Help +[08]: xref:Microsoft.PowerShell.Core.Update-Help +[09]: xref:Microsoft.PowerShell.Utility.Export-PSSession diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Comments.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Comments.md new file mode 100644 index 000000000000..a886f7457125 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Comments.md @@ -0,0 +1,391 @@ +--- +description: Describes how to use comments and lists special use cases. +Locale: en-US +ms.date: 01/10/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comments?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Comments +--- +# about_Comments + +## Short description + +Describes how to use PowerShell comments and lists special use cases. + +## Long description + +You can write comments to annotate or structure your PowerShell code to help +with readability. When your code is run, comment text is ignored by PowerShell. + +Comments provide important context to readers of the code. You should use +comments for the following purposes: + +- Explain complex code in simpler terms +- Explain why a particular approach was chosen +- Document edge cases to be aware +- Provide links to supporting reference material + +Some comments have special meaning in PowerShell. See [Special comments][04]. + +## PowerShell comment styles + +PowerShell supports two comment styles: + +- **Single-line comments** begin with hash character (`#`) and end with a + newline. The `#` can be preceded by text that's not a part of the comment, + including whitespace. Single-line comments placed on the same line as + uncommented source code are known as end-of-line comments. +- **Block comments** begin with `<#` and end with `#>`. A block comment can + span any number of lines, and can be included before, after or in the middle + of uncommented source code. All text within the block is treated as part of + the same comment, including whitespace. + + > [!IMPORTANT] + > You can include single-line comments within a block comment. However, you + > can't nest block comments. If you attempt to nest block comments, the outer + > block comment ends at the first `#>` encountered. + +## Examples + +### Example 1: Single-line comment + +```powershell +# This is a single-line comment. +# This is also a single-line comment. +``` + +### Example 2: Block comment + +```powershell +<# + This is a block comment. + Text within the block is a part of the same comment. +Whitespace is unimportant in a block comment. +#> +``` + +### Example 3: End-of-line comment + +```powershell +$var = 4 # This is an end-of-line comment +``` + +### Example 4: Inline block comment + +```powershell +'Foo'; <# This is an inline block comment #> 'Bar' +``` + +### Example 5: Full example + +```powershell +<# + .DESCRIPTION + Demonstrates PowerShell's different comment styles. +#> +param ( + [string] $Param1, # End-of-line comment + <# Inline block comment #> $Param2 +) + +$var = 1, <# Inline block comment #> 2, 2 + +# Single-line comment. +# Another single-line comment. +$var.Where( + <# Arg1 note #> { $_ -eq 2 }, + <# Arg2 note #> 'First', + <# Arg3 note #> 1 +) +``` + +## Special comments + +PowerShell includes several comment keywords to support specific uses. + +### Comment-based help + +You can write comment-based help content for functions and scripts using either +single-line or block comments. Users can use the [Get-Help][14] cmdlet to view +comment-based help for a function or script. PowerShell defines 15 comment +keywords that can be used to provide information such as the description and +example usage. + +```powershell +<# + .DESCRIPTION + Comment-based help using a block comment. +#> +function Get-Function { } +``` + +```powershell +# .DESCRIPTION +# Comment-based help using multiple single-line comments. +function Get-Function { } +``` + +For more information, see: + +- [about_Comment_Based_Help][05] +- [Writing Comment-Based Help Topics][03] + +### `#Requires` + +The `#Requires` statement prevents a script from running unless the current +PowerShell session meets the specified prerequisites. `#Requires` can appear on +any line in a script, but is processed in the same manner regardless of +position. + +```powershell +#Requires -Modules AzureRM.Netcore +#Requires -Version 6.0 + +param ( + [Parameter(Mandatory)] + [string[]] $Path +) +``` + +For more information, see [about_Requires][09]. + +### Signature block + +Scripts can be signed so that they comply with PowerShell execution policies. +Once signed, a signature block is added to the end of a script. This block +takes the form of multiple single-line comments, which are read by PowerShell +before the script is executed. + +```powershell +# SIG # Begin signature block +# ... +# SIG # End signature block +``` + +For more information, see [about_signing][10]. + +### Shebang + +On Unix-like systems, a [shebang][12] (`#!`) is a directive used at the +beginning of a script to indicate which shell should be used to run the script. +Shebang isn't a part of the PowerShell language. PowerShell interprets it as a +regular comment. Shebang is interpreted by the operating system. + +In the following example, the shebang ensures PowerShell runs the script when +the script is invoked from a non-PowerShell context. + +```powershell +#!/usr/bin/env pwsh +Write-Host 'Begin script' +``` + +### Code editor region markers + +Some code editors support region markers that allow you to collapse and expand +sections of code. For PowerShell, the region markers are comments that begin +with `#region` and end with `#endregion`. The region markers must be at the +beginning of a line. The region markers are supported in the PowerShell ISE and +in Visual Studio Code with the PowerShell extension. The region markers aren't +a part of the PowerShell language. PowerShell interprets them as regular +comments. + +For more information, see the _Folding_ section of the +[Basic editing in Visual Studio Code][11] documentation. + +## Comments in string tokens + +`#` and `<# #>` don't have special meaning within an [expandable][06] or +[verbatim][07] string. PowerShell interprets the characters literally. + +```powershell +PS> '# This is not interpreted as a comment.' +# This is not interpreted as a comment. + +PS> "This is <# also not interpreted #> as a comment." +This is <# also not interpreted #> as a comment. +``` + +However, certain PowerShell features are designed to work with strings that +contain comments. Interpretation of the comment is dependant on the specific +feature. + +### Regular expression comments + +Regular expressions (regex) in PowerShell use the [.NET regex][02] engine, +which supports two comment styles: + +- Inline comment (`(?#)`) +- End-of-line comment (`#`) + +Regex comments are supported by all regex-based features in PowerShell. For +example: + +```powershell +PS> 'book' -match '(?# This is an inline comment)oo' +True + +PS> 'book' -match '(?x)oo# This is an end-of-line comment' +True + +PS> $regex = 'oo # This is an end-of-line comment' +PS> 'book' -split $regex, 0, 'IgnorePatternWhitespace' +b +k +``` + +> [!NOTE] +> An end-of-line regex comment requires either the `(?x)` construct or the +> [`IgnorePatternWhitespace`][24] option. + +For more information, see: + +- [about_Regular_Expressions][08] +- [Miscellaneous Constructs in Regular Expressions][01] + +### JSON comments + +Beginning in PowerShell 6.0, the [ConvertFrom-Json][16] cmdlet supports the +following JSON comment styles: + +- Single-line comment (`//`) +- Block comment (`/* */`) + +> [!NOTE] +> The [Invoke-RestMethod][22] cmdlet automatically deserializes received JSON +> data. In PowerShell 6.0 onwards, comments are permitted in the JSON data. + +For example: + +```powershell +'{ + "Foo": "Bar" // This is a single-line comment +}' | ConvertFrom-Json +``` + +```Output +Foo +--- +Bar +``` + +> [!WARNING] +> Beginning in PowerShell 7.4, the [Test-Json][23] cmdlet no longer supports +> JSON with comments. An error is returned if the JSON includes comments. In +> supported versions prior to 7.4, `Test-Json` successfully parses JSON with +> comments. In PowerShell 7.5, `Test-Json` includes an option to ignore +> JSON comments. + +### CSV comments + +[Import-Csv][21] and [ConvertFrom-Csv][15] support the W3C Extended Log format. +Lines starting with the hash character (`#`) are treated as comments and +ignored unless the comment starts with `#Fields:` and contains delimited list +of column names. In that case, the cmdlet uses those column names. This is the +standard format for Windows IIS and other web server logs. For more +information, see [Extended Log File Format][13]. + +```powershell +@' +# This is a CSV comment +Col1,Col2 +Val1,Val2 +'@ | ConvertFrom-Csv +``` + +```Output +Col1 Col2 +---- ---- +Val1 Val2 +``` + +In Windows PowerShell 5.1, the default [Export-Csv][20] and [ConvertTo-Csv][19] +behavior is to include type information in the form of a `#TYPE` comment. +Beginning in PowerShell 6.0, the default is not to include the comment, but +this can be overridden with the **IncludeTypeInformation** parameter. + +```powershell +[pscustomobject] @{ Foo = 'Bar' } | ConvertTo-Csv -IncludeTypeInformation +``` + +```Output +#TYPE System.Management.Automation.PSCustomObject +"Foo" +"Bar" +``` + +When a `#TYPE` comment is included in CSV data, `Import-Csv` and +`ConvertFrom-Csv` use this information to set the `pstypenames` property of the +deserialized object(s). + +```powershell +class Test { $Foo = 'Bar' } +$test = [Test]::new() + +$var = $test | ConvertTo-Csv -IncludeTypeInformation | ConvertFrom-Csv +$var.pstypenames +``` + +```Output +Test +CSV:Test +``` + +### `ConvertFrom-StringData` comments + +Within its string data, the [ConvertFrom-StringData][17] cmdlet treats lines +beginning with `#` as comments. For more information, see: + +- [Example 3: Convert a here-string containing a comment][18] + +## Notes + +- Block comments can't be nested. In the following example, `Baz` is not a + part of the comment. + + ```powershell + <# + 'Foo' + <# 'Bar' #> + 'Baz' + #> + ``` + +- `<# #>` has no special meaning within a single-line comment. `#` has no + special meaning within a block comment. +- To be treated as a comment, the comment character must not be a part + of a non-comment token. In the following example, `#Bar` and `<#Bar#>` are + a part of the `Foo...` token. Therefore, they aren't treated as comments. + + ```powershell + PS> Foo#Bar + Foo#Bar: The term 'Foo#Bar' is not recognized as a name [...] + + PS> Foo<#Bar#> + Foo<#Bar#>: The term 'Foo<#Bar#>' is not recognized as a name [...] + ``` + + +[01]: /dotnet/standard/base-types/miscellaneous-constructs-in-regular-expressions +[02]: /dotnet/standard/base-types/regular-expressions +[03]: /powershell/scripting/developer/help/writing-comment-based-help-topics +[04]: #special-comments +[05]: about_Comment_Based_Help.md +[06]: about_quoting_rules.md#double-quoted-strings +[07]: about_quoting_rules.md#single-quoted-strings +[08]: about_Regular_Expressions.md +[09]: about_Requires.md +[10]: about_signing.md +[11]: https://code.visualstudio.com/docs/editor/codebasics#_folding +[12]: https://wikipedia.org/wiki/Shebang_(Unix) +[13]: https://www.w3.org/TR/WD-logfile.html +[14]: xref:Microsoft.PowerShell.Core.Get-Help +[15]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Csv +[16]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Json +[17]: xref:Microsoft.PowerShell.Utility.ConvertFrom-StringData +[18]: xref:Microsoft.PowerShell.Utility.ConvertFrom-StringData#example-3-convert-a-here-string-containing-a-comment +[19]: xref:Microsoft.PowerShell.Utility.ConvertTo-Csv +[20]: xref:Microsoft.PowerShell.Utility.Export-Csv +[21]: xref:Microsoft.PowerShell.Utility.Import-Csv +[22]: xref:Microsoft.PowerShell.Utility.Invoke-RestMethod +[23]: xref:Microsoft.PowerShell.Utility.Test-Json +[24]: xref:System.Text.RegularExpressions.RegexOptions#system-text-regularexpressions-regexoptions-ignorepatternwhitespace diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md new file mode 100644 index 000000000000..38b7d2d573ce --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -0,0 +1,768 @@ +--- +description: Describes the parameters that can be used with any cmdlet. +Locale: en-US +ms.date: 07/02/2024 +no-loc: [Debug, Verbose, Confirm] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_CommonParameters +--- +# about_CommonParameters + +## Short description + +Describes the parameters that can be used with any cmdlet. + +## Long description + +The common parameters are a set of cmdlet parameters that you can use with any +cmdlet. They're implemented by PowerShell, not by the cmdlet developer, and +they're automatically available to any cmdlet. + +You can use the common parameters with any cmdlet, but they might not have an +effect on all cmdlets. For example, if a cmdlet doesn't generate any verbose +output, using the **Verbose** common parameter has no effect. + +The common parameters are also available on advanced functions that use the +`CmdletBinding` attribute or the `Parameter` attribute. When you use these +attributes, PowerShell automatically adds the Common Parameters. You can't +create any parameters that use the same names as the Common Parameters. + +Several common parameters override system defaults or preferences that you set +using the PowerShell preference variables. Unlike the preference variables, the +common parameters affect only the commands in which they're used. + +For more information, see [about_Preference_Variables][03]. + +The following list displays the common parameters. Their aliases are listed in +parentheses. + +- **Debug** (db) +- **ErrorAction** (ea) +- **ErrorVariable** (ev) +- **InformationAction** (infa) +- **InformationVariable** (iv) +- **OutVariable** (ov) +- **OutBuffer** (ob) +- **PipelineVariable** (pv) +- **ProgressAction** (proga) +- **Verbose** (vb) +- **WarningAction** (wa) +- **WarningVariable** (wv) + +The **Action** parameters are **ActionPreference** type values. +**ActionPreference** is an enumeration with the following values: + +| Name | Value | +| ------------------ | ----- | +| `Break` | 6 | +| `Suspend` | 5 | +| `Ignore` | 4 | +| `Inquire` | 3 | +| `Continue` | 2 | +| `Stop` | 1 | +| `SilentlyContinue` | 0 | + +You may use the name or the value with the parameter. + +In addition to the common parameters, many cmdlets offer risk mitigation +parameters. Cmdlets that involve risk to the system or to user data usually +offer these parameters. + +The risk mitigation parameters are: + +- **WhatIf** (wi) +- **Confirm** (cf) + +## Common parameter descriptions + +### -Debug + +Displays programmer-level detail about the operation done by the command. This +parameter works only when the command generates a debugging message. For +example, this parameter works when a command contains the `Write-Debug` cmdlet. + +```yaml +Type: SwitchParameter +Aliases: db +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +By default, debugging messages aren't displayed because the value of the +`$DebugPreference` variable is **SilentlyContinue**. + +The **Debug** parameter overrides the value of the `$DebugPreference` variable +for the current command, setting the value of `$DebugPreference` to +**Continue**. + +`-Debug:$true` has the same effect as `-Debug`. Use `-Debug:$false` to +suppress the display of debugging messages when `$DebugPreference` isn't +**SilentlyContinue**, which is the default. + +### -ErrorAction + +Determines how the cmdlet responds to a non-terminating error from the command. +This parameter works only when the command generates a non-terminating error, +such as those from the `Write-Error` cmdlet. + +```yaml +Type: ActionPreference +Aliases: ea +Accepted values: Break, Suspend, Ignore, Inquire, Continue, Stop, SilentlyContinue +Required: False +Position: Named +Default value: Depends on preference variable +Accept pipeline input: False +Accept wildcard characters: False +``` + +The **ErrorAction** parameter overrides the value of the +`$ErrorActionPreference` variable for the current command. Because the default +value of the `$ErrorActionPreference` variable is **Continue**, error messages +are displayed and execution continues unless you use the **ErrorAction** +parameter. + +The **ErrorAction** parameter has no effect on terminating errors (such as +missing data, parameters that aren't valid, or insufficient permissions) that +prevent a command from completing successfully. + +- `Break` Enters the debugger when an error occurs or an exception is raised. +- `Continue` displays the error message and continues executing the command. + `Continue` is the default. +- `Ignore` suppresses the error message and continues executing the command. + Unlike **SilentlyContinue**, **Ignore** doesn't add the error message to the + `$Error` automatic variable. The **Ignore** value is introduced in PowerShell + 3.0. +- `Inquire` displays the error message and prompts you for confirmation before + continuing execution. This value is rarely used. +- `SilentlyContinue` suppresses the error message and continues executing the + command. +- `Stop` displays the error message and stops executing the command. +- `Suspend` is only available for workflows which aren't supported in + PowerShell 6 and beyond. + +> [!NOTE] +> The **ErrorAction** parameter overrides, but doesn't replace the value of the +> `$ErrorActionPreference` variable when the parameter is used in a command to +> run a script or function. + +### -ErrorVariable + +Error records are automatically store in the `$Error` automatic variable. For +more information, see [about_Automatic_Variables][02]. + +When you use the **ErrorVariable** parameter on a command, PowerShell also +stores the error records emitted by the command in the variable specified by +the parameter. + +```yaml +Type: String +Aliases: ev +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +By default, new error messages overwrite error messages that are already stored +in the variable. To append the error message to the variable content, put a +plus sign (`+`) before the variable name. + +For example, the following command creates the `$a` variable and then stores any +errors in it: + +```powershell +Get-Process -Id 6 -ErrorVariable a +``` + +The following command adds any error messages to the `$a` variable: + +```powershell +Get-Process -Id 2 -ErrorVariable +a +``` + +The following command displays the contents of `$a`: + +```powershell +$a +``` + +You can use this parameter to create a variable that contains only error +messages from specific commands and doesn't affect the behavior of the `$Error` +automatic variable. The `$Error` automatic variable contains error messages +from all the commands in the session. You can use array notation, such as +`$a[0]` or `$error[1,2]` to refer to specific errors stored in the variables. + +> [!NOTE] +> The custom error variable contains all errors generated by the command, +> including errors from calls to nested functions or scripts. + +### -InformationAction + +Introduced in PowerShell 5.0. Within the command or script in which it's used, +the **InformationAction** common parameter overrides the value of the +`$InformationPreference` preference variable, which by default is set to +**SilentlyContinue**. When you use `Write-Information` in a script with +**InformationAction**, `Write-Information` values are shown depending on the +value of the **InformationAction** parameter. For more information about +`$InformationPreference`, see [about_Preference_Variables][03]. + +```yaml +Type: ActionPreference +Aliases: infa +Accepted values: Break, Suspend, Ignore, Inquire, Continue, Stop, SilentlyContinue +Required: False +Position: Named +Default value: Depends on preference variable +Accept pipeline input: False +Accept wildcard characters: False +``` + +- `Break` Enters the debugger at an occurrence of the `Write-Information` + command. +- `Stop` stops a command or script at an occurrence of the `Write-Information` + command. +- `Ignore` suppresses the informational message and continues running the + command. Unlike **SilentlyContinue**, **Ignore** completely forgets the + informational message; it doesn't add the informational message to the + information stream. +- `Inquire` displays the informational message that you specify in a + `Write-Information` command, then asks whether you want to continue. +- `Continue` displays the informational message, and continues running. +- `Suspend` isn't supported on PowerShell 6 and higher as it is only available + for workflows. +- `SilentlyContinue` no effect as the informational message aren't (Default) + displayed, and the script continues without interruption. + +> [!NOTE] +> The **InformationAction** parameter overrides, but doesn't replace the +> value of the `$InformationAction` preference variable when the parameter +> is used in a command to run a script or function. + +### -InformationVariable + +Introduced in PowerShell 5.0. When you use the **InformationVariable** common +parameter, information records are stored in the variable specified by the +parameter. And PowerShell cmdlet can write information records to the +**Information** stream. You can also use the `Write-Information` cmdlet to +write information records. + +Information records are displayed as messages in the console by default. You +can control the display of information record by using the +**InformationAction** common parameter. You can also change the behavior using +the `$InformationPreference` preference variable. For more information about +`$InformationPreference`, see [about_Preference_Variables][03]. + +> [!NOTE] +> The information variable contains all information messages generated by the +> command, including information messages from calls to nested functions or +> scripts. + +```yaml +Type: String +Aliases: iv +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +By default, new information record overwrite values that are already stored in +the variable. To append the error message to the variable content, put a plus +sign (`+`) before the variable name. + +### -OutBuffer + +Determines the number of objects to accumulate in a buffer before any objects +are sent through the pipeline. If you omit this parameter, objects are sent as +they're generated. + +```yaml +Type: Int32 +Aliases: ob +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +This resource management parameter is designed for advanced users. When you use +this parameter, PowerShell sends data to the next cmdlet in batches of +`OutBuffer + 1`. + +The following example alternates displays between to `ForEach-Object` process +blocks that use the `Write-Host` cmdlet. The display alternates in batches of +2 or `OutBuffer + 1`. + +```powershell +1..4 | ForEach-Object { + Write-Host "$($_): First"; $_ + } -OutBuffer 1 | ForEach-Object { + Write-Host "$($_): Second" } +``` + +```Output +1: First +2: First +1: Second +2: Second +3: First +4: First +3: Second +4: Second +``` + +### -OutVariable + +Stores output objects from the command in the specified variable in addition +to sending the output along the pipeline. + +```yaml +Type: String +Aliases: ov +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +To add the output to the variable, instead of replacing any output that might +already be stored there, type a plus sign (`+`) before the variable name. + +For example, the following command creates the `$out` variable and stores the +process object in it: + +```powershell +Get-Process PowerShell -OutVariable out +``` + +The following command adds the process object to the `$out` variable: + +```powershell +Get-Process iexplore -OutVariable +out +``` + +The following command displays the contents of the `$out` variable: + +```powershell +$out +``` + +> [!NOTE] +> The variable created by the **OutVariable** parameter is a +> `[System.Collections.ArrayList]`. + +### -PipelineVariable + +**PipelineVariable** allows access to the most recent value passed into the +next pipeline segment by the command that uses this parameter. Any command in +the pipeline can access the value using the named **PipelineVariable**. The +value is assigned to the variable when it's passed into the next pipeline +segment. This makes the **PipelineVariable** easier to use than a specific +temporary variable, which might need to be assigned in multiple locations. + +Unlike `$_` or `$PSItem`, using a **PipelineVariable** allows any pipeline +command to access pipeline values passed (and saved) by commands other than the +immediately preceding command. Pipeline commands can access the last value +piped from while processing the next item passing through the pipeline. This +allows a command to _feed back_ its output to a previous command (or itself). + +>[!NOTE] +> Advanced functions can have up to three script blocks: `begin`, `process`, +> and `end`. When using the **PipelineVariable** parameter with advanced +> functions, only values from the first defined script block are assigned to +> the variable as the function runs. For more information, see +> [Advanced functions][05]. PowerShell 7.2 corrects this behavior. + +```yaml +Type: String +Aliases: pv +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +Valid values are strings, the same as for any variable names. + +> [!CAUTION] +> The **PipelineVariable** is scoped to the pipeline in which it's invoked. +> Variables outside the pipeline, which use same name, are cleared before the +> pipeline is executed. The **PipelineVariable** goes out of scope when the +> pipeline terminates. If multiple commands within the pipeline specify the +> same **PipelineVariable** then there is only one shared variable. That +> variable is updated with the most recent piped output from the command that +> specifies the variable. +> +> Some _blocking_ commands collect all the pipeline items before producing any +> output, for example `Sort-Object` or `Select-Object -Last`. Any +> **PipelineVariable** assigned in a command before such a blocking command +> always contains the final piped item from the preceding command when used in +> a command after the blocking command. + +The following is an example of how **PipelineVariable** works. In this example, +the **PipelineVariable** parameter is added to a `Foreach-Object` command to +store the results of the command in variables. A range of numbers, 1 to 5, are +piped into the first `Foreach-Object` command, the results of which are stored +in a variable named `$temp`. + +The results of the first `Foreach-Object` command are piped into a second +`Foreach-Object` command, which displays the current values of `$temp` and +`$_`. + +```powershell +# Create a variable named $temp +$temp=8 +Get-Variable temp +# Note that the variable just created isn't available on the +# pipeline when -PipelineVariable creates the same variable name +1..5 | ForEach-Object -PipelineVariable temp -Begin { + Write-Host "Step1[BEGIN]:`$temp=$temp" +} -Process { + Write-Host "Step1[PROCESS]:`$temp=$temp - `$_=$_" + Write-Output $_ +} | ForEach-Object { + Write-Host "`tStep2[PROCESS]:`$temp=$temp - `$_=$_" +} +# The $temp variable is deleted when the pipeline finishes +Get-Variable temp +``` + +```Output +Name Value +---- ----- +temp 8 + +Step1[BEGIN]:$temp= +Step1[PROCESS]:$temp= - $_=1 + Step2[PROCESS]:$temp=1 - $_=1 +Step1[PROCESS]:$temp=1 - $_=2 + Step2[PROCESS]:$temp=2 - $_=2 +Step1[PROCESS]:$temp=2 - $_=3 + Step2[PROCESS]:$temp=3 - $_=3 +Step1[PROCESS]:$temp=3 - $_=4 + Step2[PROCESS]:$temp=4 - $_=4 +Step1[PROCESS]:$temp=4 - $_=5 + Step2[PROCESS]:$temp=5 - $_=5 + +Name Value +---- ----- +temp +``` + +### -ProgressAction + +Determines how PowerShell responds to progress updates generated by a script, +cmdlet, or provider, such as the progress bars generated by the +[Write-Progress][06] cmdlet. The `Write-Progress` cmdlet creates progress bars +that show a command's status. The **ProgressAction** parameter was added in +PowerShell 7.4. + +The **ProgressAction** parameter takes one of the [`ActionPreference`][07] +enumeration values: `SilentlyContinue`, `Stop`, `Continue`, `Inquire`, +`Ignore`, `Suspend`, or `Break`. + +The valid values are as follows: + +- `Break` Enters the debugger at an occurrence of the `Write-Progress` command. +- `Stop`: Doesn't display the progress bar. Instead, it displays an error + message and stops executing. +- `Inquire`: Doesn't display the progress bar. Prompts for permission to + continue. If you reply with `Y` or `A`, it displays the progress bar. +- `Continue`: (Default) Displays the progress bar and continues with execution. +- `SilentlyContinue`: Executes the command, but doesn't display the progress + bar. + +```yaml +Type: ActionPreference +Aliases: proga +Accepted values: Break, Suspend, Ignore, Inquire, Continue, Stop, SilentlyContinue +Required: False +Position: Named +Default value: Depends on preference variable +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -Verbose + +Displays detailed information about the operation done by the command. This +information resembles the information in a trace or in a transaction log. This +parameter works only when the command generates a verbose message. For example, +this parameter works when a command contains the `Write-Verbose` cmdlet. + +```yaml +Type: SwitchParameter +Aliases: vb +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +The **Verbose** parameter overrides the value of the `$VerbosePreference` +variable for the current command. Because the default value of the +`$VerbosePreference` variable is **SilentlyContinue**, verbose messages aren't +displayed by default. + +- `-Verbose:$true` has the same effect as `-Verbose` +- `-Verbose:$false` suppresses the display of verbose messages. Use this + parameter when the value of `$VerbosePreference` isn't **SilentlyContinue** + (the default). + +### -WarningAction + +Determines how the cmdlet responds to a warning from the command. **Continue** +is the default value. This parameter works only when the command generates a +warning message. For example, this parameter works when a command contains the +`Write-Warning` cmdlet. + +```yaml +Type: ActionPreference +Aliases: wa +Accepted values: Break, Suspend, Ignore, Inquire, Continue, Stop, SilentlyContinue +Required: False +Position: Named +Default value: Depends on preference variable +Accept pipeline input: False +Accept wildcard characters: False +``` + +The **WarningAction** parameter overrides the value of the `$WarningPreference` +variable for the current command. Because the default value of the +`$WarningPreference` variable is **Continue**, warnings are displayed and +execution continues unless you use the **WarningAction** parameter. + +- `Break` enters the debugger when a warning occurs. +- `Continue` displays the warning messages and continues executing the command. + `Continue` is the default. +- `Inquire` displays the warning message and prompts you for confirmation + before continuing execution. This value is rarely used. +- `SilentlyContinue` suppresses the warning message and continues executing the + command. +- `Stop` displays the warning message and stops executing the command. + +> [!NOTE] +> The **WarningAction** parameter overrides, but doesn't replace the value of +> the `$WarningAction` preference variable when the parameter is used in a +> command to run a script or function. + +### -WarningVariable + +Stores warning records about the command in the specified variable. + +```yaml +Type: String +Aliases: wv +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +All generated warnings are saved in the variable even if the warnings aren't +displayed to the user. + +To append the warnings to the variable content, instead of replacing any +warnings that might already be stored there, type a plus sign (`+`) before the +variable name. + +For example, the following command creates the `$a` variable and then stores +any warnings in it: + +```powershell +Get-Process -Id 6 -WarningVariable a +``` + +The following command adds any warnings to the `$a` variable: + +```powershell +Get-Process -Id 2 -WarningVariable +a +``` + +The following command displays the contents of `$a`: + +```powershell +$a +``` + +You can use this parameter to create a variable that contains only warnings +from specific commands. You can use array notation, such as `$a[0]` or +`$warning[1,2]` to refer to specific warnings stored in the variable. + +> [!NOTE] +> The warning variable contains all warnings generated by the command, +> including warnings from calls to nested functions or scripts. + +## Risk Management Parameter Descriptions + +### -WhatIf + +Displays a message that describes the effect of the command, instead of +executing the command. + +```yaml +Type: SwitchParameter +Aliases: wi +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +The **WhatIf** parameter overrides the value of the `$WhatIfPreference` +variable for the current command. Because the default value of the +`$WhatIfPreference` variable is 0 (disabled), **WhatIf** behavior isn't done +without the **WhatIf** parameter. For more information, see +[about_Preference_Variables][03]. + +- `$true` has the same effect as `-WhatIf`. +- `$false` suppresses the automatic WhatIf behavior that results when the value + of the `$WhatIfPreference` variable is 1. + +For example, the following command uses the `-WhatIf` parameter in a +`Remove-Item` command: + +```powershell +Remove-Item Date.csv -WhatIf +``` + +Instead of removing the item, PowerShell lists the operations it would do and +the items that would be affected. This command produces the following output: + +```Output +What if: Performing operation "Remove File" on +Target "C:\ps-test\date.csv". +``` + +### -Confirm + +Prompts you for confirmation before executing the command. + +```yaml +Type: SwitchParameter +Aliases: cf +Required: False +Position: Named +Default value: Depends on preference variable +Accept pipeline input: False +Accept wildcard characters: False +``` + +The **Confirm** parameter overrides the value of the `$ConfirmPreference` +variable for the current command. The default value is true. For more +information, see [about_Preference_Variables][03]. + +- `$true` has the same effect as `-Confirm`. +- `$false` suppresses automatic confirmation, which occurs when the value of + `$ConfirmPreference` is less than or equal to the estimated risk of the + cmdlet. + +For example, the following command uses the **Confirm** parameter with a +`Remove-Item` command. Before removing the item, PowerShell lists the +operations it would do and the items that would be affected, and asks for +approval. + +```powershell +PS C:\ps-test> Remove-Item tmp*.txt -Confirm + +Confirm +Are you sure you want to perform this action? +Performing operation "Remove File" on Target " C:\ps-test\tmp1.txt +[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend +[?] Help (default is "Y"): +``` + +The Confirm response options are as follows: + +| Response | Result | +| ------------------ | --------------------------------------------------- | +| `Yes` (`Y`) | Perform the action. | +| `Yes to All` (`A`) | Perform all actions and suppress subsequent Confirm | +| | queries for this command. | +| `No` (`N`): | Don't perform the action. | +| `No to All` (`L`): | Don't perform any actions and suppress subsequent | +| | Confirm queries for this command. | +| `Suspend` (`S`): | Pause the command and create a temporary session. | +| `Help` (`?`) | Display help for these options. | + +The **Suspend** option places the command on hold and creates a temporary +nested session in which you can work until you're ready to choose a **Confirm** +option. The command prompt for the nested session has two extra carets (>>) to +indicate that it's a child operation of the original parent command. You can +run commands and scripts in the nested session. To end the nested session and +return to the Confirm options for the original command, type "exit". + +In the following example, the **Suspend** option (S) is used to halt a command +temporarily while the user checks the help for a command parameter. After +obtaining the needed information, the user types "exit" to end the nested +prompt and then selects the Yes (y) response to the Confirm query. + +```powershell +PS C:\ps-test> New-Item -ItemType File -Name Test.txt -Confirm + +Confirm +Are you sure you want to perform this action? + +Performing operation "Create File" on Target "Destination: +C:\ps-test\test.txt". +[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default +is "Y"): s + +PS C:\ps-test> Get-Help New-Item -Parameter ItemType + +-ItemType +Specifies the provider-specified type of the new item. + +Required? false +Position? named +Default value +Accept pipeline input? true (ByPropertyName) +Accept wildcard characters? false + +PS C:\ps-test> exit + +Confirm +Are you sure you want to perform this action? +Performing operation "Create File" on Target "Destination: C:\ps-test\test +.txt". +[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (defau +lt is "Y"): y + +Directory: C:\ps-test + +Mode LastWriteTime Length Name +---- ------------- ------ ---- +-a--- 8/27/2010 2:41 PM 0 test.txt +``` + +## See also + +- [about_Preference_Variables][03] +- [Write-Debug][11] +- [Write-Error][12] +- [Write-Verbose][13] +- [Write-Warning][14] + + +[02]: about_Automatic_Variables.md +[03]: about_Preference_Variables.md +[05]: about_functions_advanced.md +[06]: xref:Microsoft.PowerShell.Utility.Write-Progress +[07]: xref:System.Management.Automation.ActionPreference +[11]: xref:Microsoft.PowerShell.Utility.Write-Debug +[12]: xref:Microsoft.PowerShell.Utility.Write-Error +[13]: xref:Microsoft.PowerShell.Utility.Write-Verbose +[14]: xref:Microsoft.PowerShell.Utility.Write-Warning diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Comparison_Operators.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Comparison_Operators.md new file mode 100644 index 000000000000..05d3e6cf92b2 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Comparison_Operators.md @@ -0,0 +1,804 @@ +--- +description: Describes the operators that compare values in PowerShell. +Locale: en-US +ms.date: 06/06/2024 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Comparison_Operators +--- +# about_Comparison_Operators + +## Short description + +The comparison operators in PowerShell can either compare two values or filter +elements of a collection against an input value. + +## Long description + +Comparison operators let you compare values or finding values that match +specified patterns. PowerShell includes the following comparison operators: + +**Equality** + +- `-eq`, `-ieq`, `-ceq` - equals +- `-ne`, `-ine`, `-cne` - not equals +- `-gt`, `-igt`, `-cgt` - greater than +- `-ge`, `-ige`, `-cge` - greater than or equal +- `-lt`, `-ilt`, `-clt` - less than +- `-le`, `-ile`, `-cle` - less than or equal + +**Matching** + +- `-like`, `-ilike`, `-clike` - string matches wildcard pattern +- `-notlike`, `-inotlike`, `-cnotlike` - string doesn't match wildcard pattern +- `-match`, `-imatch`, `-cmatch` - string matches regex pattern +- `-notmatch`, `-inotmatch`, `-cnotmatch` - string doesn't match regex pattern + +**Replacement** + +- `-replace`, `-ireplace`, `-creplace` - replaces strings matching a regex + pattern + +**Containment** + +- `-contains`, `-icontains`, `-ccontains` - collection contains a value +- `-notcontains`, `-inotcontains`, `-cnotcontains` - collection doesn't + contain a value +- `-in` - value is in a collection +- `-notin` - value isn't in a collection + +**Type** + +- `-is` - both objects are the same type +- `-isnot` - the objects aren't the same type + +## Common features + +String comparisons are case-insensitive unless you use the explicit +case-sensitive operator. To make a comparison operator case-sensitive, add a +`c` after the `-`. For example, `-ceq` is the case-sensitive version of `-eq`. +To make the case-insensitivity explicit, add an `i` after `-`. For example, +`-ieq` is the explicitly case-insensitive version of `-eq`. + +String comparisons use the [InvariantCulture][01] for both case-sensitive and +case-insensitive comparisons. The comparisons are between unicode code points +and don't use culture-specific collation ordering. The results are the same +regardless of the current culture. + +When the left-hand value in the comparison expression is a [scalar][15] value, +the operator returns a **Boolean** value. When the left-hand value in the +expression is a collection, the operator returns the elements of the collection +that match the right-hand value of the expression. Right-hand values are always +treated as singleton instances, even when they're collections. The comparison +operators can't effectively compare collections to collections. + +If there are no matches in the collection, comparison operators return an empty +array. For example: + +```powershell +$a = (1, 2) -eq 3 +$a.GetType().Name +$a.Count +``` + +```output +Object[] +0 +``` + +There are a few exceptions: + +- The containment and type operators always return a **Boolean** value +- The `-replace` operator returns the replacement result +- The `-match` and `-notmatch` operators also populate the `$Matches` automatic + variable unless the left-hand side of the expression is a collection. + +## Equality operators + +### -eq and -ne + +When the left-hand side is scalar, `-eq` returns **True** if the right-hand +side is equivalent, otherwise, `-eq` returns **False**. `-ne` does the +opposite; it returns **False** when both sides are equivalent; otherwise, `-ne` +returns **True**. + +Example: + +```powershell +2 -eq 2 # Output: True +2 -eq 3 # Output: False +"abc" -eq "abc" # Output: True +"abc" -eq "abc", "def" # Output: False +"abc" -ne "def" # Output: True +"abc" -ne "abc" # Output: False +"abc" -ne "abc", "def" # Output: True +``` + +When the left-hand side is a collection, `-eq` returns those members that match +the right-hand side, while `-ne` filters them out. + +Example: + +```powershell +1,2,3 -eq 2 # Output: 2 +"abc", "def" -eq "abc" # Output: abc +"abc", "def" -ne "abc" # Output: def +``` + +These operators process all elements of the collection. Example: + +```powershell +"zzz", "def", "zzz" -eq "zzz" +``` + +```output +zzz +zzz +``` + +The equality operator can compare objects of different types. It's important to +understand that the value on the right-hand side of the comparison can be +converted to the type of the left-hand side value for comparison. + +For example, the string `'1.0'` is converted to an integer to be compared to +the value `1`. This example returns `True`. + +```powershell +PS> 1 -eq '1.0' +True +``` + +In this example, the value `1` is converted to a string to be compared to +string `'1.0'`. This example returns `False`. + +```powershell +PS> '1.0' -eq 1 +False +``` + +The equality operators accept any two objects, not just a scalar or collection. +But the comparison result isn't guaranteed to be meaningful for the end-user. +The following example demonstrates the issue. + +```powershell +class MyFileInfoSet { + [String]$File + [Int64]$Size +} +$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032} +$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032} +$a -eq $b +``` + +```Output +False +``` + +In this example, we created two objects with identical properties. Yet, the +equality test result is **False** because they're different objects. To create +comparable classes, you need to implement [System.IEquatable\][03] in your +class. The following example demonstrates the partial implementation of a +**MyFileInfoSet** class that implements [System.IEquatable\][03] and has two +properties, **File** and **Size**. The `Equals()` method returns **True** if +the File and Size properties of two **MyFileInfoSet** objects are the same. + +```powershell +class MyFileInfoSet : System.IEquatable[Object] { + [String]$File + [Int64]$Size + + [bool] Equals([Object] $obj) { + return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size) + } +} +$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032} +$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032} +$a -eq $b +``` + +```Output +True +``` + +A prominent example of comparing arbitrary objects is to find out if they're +null. But if you need to determine whether a variable is `$null`, you must put +`$null` on the left-hand side of the equality operator. Putting it on the +right-hand side doesn't do what you expect. + +For example, let `$a` be an array containing null elements: + +```powershell +$a = 1, 2, $null, 4, $null, 6 +``` + +The following tests that `$a` isn't null. + +```powershell +$null -ne $a +``` + +```output +True +``` + +The following, however, filers out all null elements from `$a`: + +```powershell +$a -ne $null # Output: 1, 2, 4, 6 +``` + +```output +1 +2 +4 +6 +``` + +### -gt, -ge, -lt, and -le + +`-gt`, `-ge`, `-lt`, and `-le` behave very similarly. When both sides are +scalar they return **True** or **False** depending on how the two sides +compare: + +| Operator | Returns True when... | +| -------- | -------------------------------------- | +| `-gt` | The left-hand side is greater | +| `-ge` | The left-hand side is greater or equal | +| `-lt` | The left-hand side is smaller | +| `-le` | The left-hand side is smaller or equal | + +In the following examples, all statements return **True**. + +```powershell +8 -gt 6 # Output: True +8 -ge 8 # Output: True +6 -lt 8 # Output: True +8 -le 8 # Output: True +``` + +> [!NOTE] +> In most programming languages the greater-than operator is `>`. In +> PowerShell, this character is used for redirection. For details, see +> [about_Redirection][09]. + +When the left-hand side is a collection, these operators compare each member of +the collection with the right-hand side. Depending on their logic, they either +keep or discard the member. + +Example: + +```powershell +$a=5, 6, 7, 8, 9 + +Write-Output "Test collection:" +$a + +Write-Output "`nMembers greater than 7" +$a -gt 7 + +Write-Output "`nMembers greater than or equal to 7" +$a -ge 7 + +Write-Output "`nMembers smaller than 7" +$a -lt 7 + +Write-Output "`nMembers smaller than or equal to 7" +$a -le 7 +``` + +```output +Test collection: +5 +6 +7 +8 +9 + +Members greater than 7 +8 +9 + +Members greater than or equal to 7 +7 +8 +9 + +Members smaller than 7 +5 +6 + +Members smaller than or equal to 7 +5 +6 +7 +``` + +These operators work with any class that implements [System.IComparable][02]. + +Examples: + +```powershell +# Date comparison +[DateTime]'2001-11-12' -lt [DateTime]'2020-08-01' # True + +# Sorting order comparison +'a' -lt 'z' # True; 'a' comes before 'z' +'macOS' -ilt 'MacOS' # False +'MacOS' -ilt 'macOS' # False +'macOS' -clt 'MacOS' # True; 'm' comes before 'M' +``` + +The following example demonstrates that there is no symbol on an American +QWERTY keyboard that gets sorted after 'a'. It feeds a set containing all such +symbols to the `-gt` operator to compare them against 'a'. The output is an +empty array. + +```powershell +$a=' ','`','~','!','@','#','$','%','^','&','*','(',')','_','+','-','=', + '{','}','[',']',':',';','"','''','\','|','/','?','.','>',',','<' +$a -gt 'a' +# Output: Nothing +``` + +If the two sides of the operators aren't reasonably comparable, these operators +raise a non-terminating error. + +## Matching operators + +The matching operators (`-like`, `-notlike`, `-match`, and `-notmatch`) find +elements that match or don't match a specified pattern. The pattern for `-like` +and `-notlike` is a wildcard expression (containing `*`, `?`, and `[ ]`), while +`-match` and `-notmatch` accept a regular expression (Regex). + +The syntax is: + +``` + -like + -notlike + -match + -notmatch +``` + +When the input of these operators is a scalar value, they return a **Boolean** +value. + +When the input is a collection of values, each item in the collection is +converted to a string for comparison. The `-match` and `-notmatch` operators +return any matching and non-matching members respectively. However, the `-like` +and `-notlike` operators return the members as strings. The string returned for +a member of the collection by `-like` and `-notlike` is the string the operator +used for the comparison and is obtained by casting the member to a string. + +### -like and -notlike + +`-like` and `-notlike` behave similarly to `-eq` and `-ne`, but the right-hand +side could be a string containing [wildcards][11]. + +Example: + +```powershell +"PowerShell" -like "*shell" # Output: True +"PowerShell" -notlike "*shell" # Output: False +"PowerShell" -like "Power?hell" # Output: True +"PowerShell" -notlike "Power?hell" # Output: False +"PowerShell" -like "Power[p-w]hell" # Output: True +"PowerShell" -notlike "Power[p-w]hell" # Output: False + +"PowerShell", "Server" -like "*shell" # Output: PowerShell +"PowerShell", "Server" -notlike "*shell" # Output: Server +``` + +### -match and -notmatch + +`-match` and `-notmatch` use regular expressions to search for pattern in the +left-hand side values. Regular expressions can match complex patterns like +email addresses, UNC paths, or formatted phone numbers. The right-hand side +string must adhere to the [regular expressions][10] rules. + +Scalar examples: + +```powershell +# Partial match test, showing how differently -match and -like behave +"PowerShell" -match 'shell' # Output: True +"PowerShell" -like 'shell' # Output: False + +# Regex syntax test +"PowerShell" -match '^Power\w+' # Output: True +'bag' -notmatch 'b[iou]g' # Output: True +``` + +If the input is a collection, the operators return the matching members of that +collection. + +Collection examples: + +```powershell +"PowerShell", "Super PowerShell", "Power's hell" -match '^Power\w+' +# Output: PowerShell + +"Rhell", "Chell", "Mel", "Smell", "Shell" -match "hell" +# Output: Rhell, Chell, Shell + +"Bag", "Beg", "Big", "Bog", "Bug" -match 'b[iou]g' +#Output: Big, Bog, Bug + +"Bag", "Beg", "Big", "Bog", "Bug" -notmatch 'b[iou]g' +#Output: Bag, Beg +``` + +`-match` and `-notmatch` support regex capture groups. Each time they run on +scalar input, and the `-match` result is **True**, or the `-notmatch` result is +**False**, they overwrite the `$Matches` automatic variable. `$Matches` is a +**Hashtable** that always has a key named '0', which stores the entire match. +If the regular expression contains capture groups, the `$Matches` contains +additional keys for each group. + +It's important to note that the `$Matches` hashtable contains only the first +occurrence of any matching pattern. + +Example: + +```powershell +$string = 'The last logged on user was CONTOSO\jsmith' +$string -match 'was (?.+)\\(?.+)' + +$Matches + +Write-Output "`nDomain name:" +$Matches.domain + +Write-Output "`nUser name:" +$Matches.user +``` + +```output +True + +Name Value +---- ----- +domain CONTOSO +user jsmith +0 was CONTOSO\jsmith + +Domain name: +CONTOSO + +User name: +jsmith +``` + +When the `-match` result is **False**, or the `-notmatch` result is **True**, +or when the input is a collection, the `$Matches` automatic variable isn't +overwritten. Consequently, it will contain the previously set value, or `$null` +if the variable hasn't been set. When referencing `$Matches` after invoking one +of these operators, consider verifying that the variable was set by the current +operator invocation using a condition statement. + +Example: + +```powershell +if ("1.0.0" -match '(.*?)') { + $Matches +} +``` + +For details, see [about_Regular_Expressions][10] and +[about_Automatic_Variables][06]. + +## Replacement operator + +### Replacement with regular expressions + +Like `-match`, the `-replace` operator uses regular expressions to find the +specified pattern. But unlike `-match`, it replaces the matches with another +specified value. + +Syntax: + +``` + -replace , +``` + +The operator replaces all or part of a value with the specified value using +regular expressions. You can use the operator for many administrative tasks, +such as renaming files. For example, the following command changes the file +name extensions of all `.txt` files to `.log`: + +```powershell +Get-ChildItem *.txt | Rename-Item -NewName { $_.name -replace '\.txt$','.log' } +``` + +By default, the `-replace` operator is case-insensitive. To make it case +sensitive, use `-creplace`. To make it explicitly case-insensitive, use +`-ireplace`. + +Examples: + +```powershell +"book" -ireplace "B", "C" # Case insensitive +"book" -creplace "B", "C" # Case-sensitive; hence, nothing to replace +``` + +```Output +Cook +book +``` + +Beginning in PowerShell 7.2, when the left-hand operand in a `-replace` +operator statement isn't a string, that operand is converted to a string. +PowerShell does a culture-insensitive string conversion. + +For example, if your culture is set to French (fr), the culture-sensitive +string conversion of value `1.2` is `1,2`. + +Prior to PowerShell 7.2: + +```powershell +PS> [cultureinfo]::CurrentCulture = 'fr' +PS> 1.2 -replace ',' +12 +``` + +In PowerShell 7.2 and later: + +```powershell +PS> [cultureinfo]::CurrentCulture = 'fr' +PS> 1.2 -replace ',' +1.2 +``` + +### Regular expressions substitutions + +It's also possible to use regular expressions to dynamically replace text using +capturing groups, and substitutions. Capture groups can be referenced in the +`` string using the dollar sign (`$`) character before the group +identifier. + +In the following example, the `-replace` operator accepts a username in the +form of `DomainName\Username` and converts to the `Username@DomainName` format: + +```powershell +$SearchExp = '^(?[\w-.]+)\\(?[\w-.]+)$' +$ReplaceExp = '${Username}@${DomainName}' + +'Contoso.local\John.Doe' -replace $SearchExp, $ReplaceExp +``` + +```output +John.Doe@Contoso.local +``` + +> [!WARNING] +> The `$` character has syntactic roles in both PowerShell and regular +> expressions: +> +> - In PowerShell, between double quotation marks, it designates variables and +> acts as a subexpression operator. +> - In Regex search strings, it denotes end of the line. +> - In Regex substitution strings, it denotes captured groups. Be sure +> to either put your regular expressions between single quotation marks or +> insert a backtick (`` ` ``) character before them. + +For example: + +```powershell +$1 = 'Goodbye' + +'Hello World' -replace '(\w+) \w+', "$1 Universe" +# Output: Goodbye Universe + +'Hello World' -replace '(\w+) \w+', '$1 Universe' +# Output: Hello Universe +``` + +`$$` in Regex denotes a literal `$`. This `$$` in the substitution string to +include a literal `$` in the resulting replacement. For example: + +```powershell +'5.72' -replace '(.+)', '$ $1' # Output: $ 5.72 +'5.72' -replace '(.+)', '$$$1' # Output: $5.72 +'5.72' -replace '(.+)', '$$1' # Output: $1 +``` + +To learn more, see [about_Regular_Expressions][10] and +[Substitutions in Regular Expressions][05]. + +### Substituting in a collection + +When the `` to the `-replace` operator is a collection, PowerShell +applies the replacement to every value in the collection. For example: + +```powershell +"B1","B2","B3","B4","B5" -replace "B", 'a' +a1 +a2 +a3 +a4 +a5 +``` + +### Replacement with a script block + +In PowerShell 6 and later, the `-replace` operator also accepts a script block +that performs the replacement. The script block runs once for every match. + +Syntax: + +```powershell + -replace , {} +``` + +Within the script block, use the `$_` automatic variable to access the input +text being replaced and other useful information. This variable's class type is +[System.Text.RegularExpressions.Match][04]. + +The following example replaces each sequence of three digits with the character +equivalents. The script block runs for each set of three digits that needs to +be replaced. + +```powershell +"072101108108111" -replace "\d{3}", {return [char][int]$_.Value} +``` + +```output +Hello +``` + +## Containment operators + +The containment operators (`-contains`, `-notcontains`, `-in`, and `-notin`) +are similar to the equality operators, except that they always return a +**Boolean** value, even when the input is a collection. These operators stop +comparing as soon as they detect the first match, whereas the equality +operators evaluate all input members. In a very large collection, these +operators return quicker than the equality operators. + +### -contains and -notcontains + +Syntax: + +```Syntax + -contains + -notcontains +``` + +These operators tell whether a set includes a certain element. `-contains` +returns **True** when the right-hand side (scalar-object) matches one of the +elements in the set. `-notcontains` returns False instead. + +Examples: + +```powershell +"abc", "def" -contains "def" # Output: True +"abc", "def" -notcontains "def" # Output: False +"Windows", "PowerShell" -contains "Shell" # Output: False +"Windows", "PowerShell" -notcontains "Shell" # Output: True +"abc", "def", "ghi" -contains "abc", "def" # Output: False +"abc", "def", "ghi" -notcontains "abc", "def" # Output: True +``` + +More complex examples: + +```powershell +$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS", + "ContosoDHCP","ContosoWSUS" +$thisComputer = "ContosoDC2" + +$DomainServers -contains $thisComputer +# Output: True +``` + +When the right-hand side operand is a collection, these operators convert the +value to its string representation before comparing it to the left-hand side +collection. + +```powershell +$a = "abc", "def" +"abc", "def", "ghi" -contains $a # Output: False + +# The following statements are equivalent +$a, "ghi" -contains $a # Output: True +"$a", "ghi" -contains $a # Output: True +"abc def", "ghi" -contains $a # Output: True +``` + +### -in and -notin + +Syntax: + +```Syntax + -in + -notin +``` + +The `-in` and `-notin` operators were introduced in PowerShell 3 as the +syntactic reverse of the of `-contains` and `-notcontains` operators. `-in` +returns **True** when the left-hand side `` matches one of the +elements in the collection. `-notin` returns **False** instead. + +The following examples do the same thing that the examples for `-contains` and +`-notcontains` do, but they're written with `-in` and `-notin` instead. + +```powershell +"def" -in "abc", "def" # Output: True +"def" -notin "abc", "def" # Output: False +"Shell" -in "Windows", "PowerShell" # Output: False +"Shell" -notin "Windows", "PowerShell" # Output: True +"abc", "def" -in "abc", "def", "ghi" # Output: False +"abc", "def" -notin "abc", "def", "ghi" # Output: True +``` + +More complex examples: + +```powershell +$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS", + "ContosoDHCP","ContosoWSUS" +$thisComputer = "ContosoDC2" + +$thisComputer -in $DomainServers +# Output: True +``` + +When the left-hand side operand is a collection, these operators convert the +value to its string representation before comparing it to the right-hand side +collection. + +```powershell +$a = "abc", "def" +$a -in "abc", "def", "ghi" # Output: False + +# The following statements are equivalent +$a -in $a, "ghi" # Output: True +$a -in "$a", "ghi" # Output: True +$a -in "abc def", "ghi" # Output: True +``` + +## Type comparison + +The type comparison operators (`-is` and `-isnot`) are used to determine if an +object is a specific type. + +Syntax: + +```powershell + -is + -isnot +``` + +Example: + +```powershell +$a = 1 +$b = "1" +$a -is [int] # Output: True +$a -is $b.GetType() # Output: False +$b -isnot [int] # Output: True +$a -isnot $b.GetType() # Output: True +``` + +## See also + +- [about_Booleans][07] +- [about_Operators][08] +- [about_Regular_Expressions][10] +- [about_Wildcards][11] +- [Compare-Object][14] +- [Foreach-Object][12] +- [Where-Object][13] + + +[01]: /dotnet/api/system.globalization.cultureinfo.invariantculture +[02]: /dotnet/api/system.icomparable +[03]: /dotnet/api/system.iequatable-1 +[04]: /dotnet/api/system.text.regularexpressions.match +[05]: /dotnet/standard/base-types/substitutions-in-regular-expressions +[06]: about_Automatic_Variables.md +[07]: about_Booleans.md +[08]: about_Operators.md +[09]: about_Redirection.md#potential-confusion-with-comparison-operators +[10]: about_Regular_Expressions.md +[11]: about_Wildcards.md +[12]: xref:Microsoft.PowerShell.Core.ForEach-Object +[13]: xref:Microsoft.PowerShell.Core.Where-Object +[14]: xref:Microsoft.PowerShell.Utility.Compare-Object +[15]: /powershell/scripting/learn/glossary#scalar-value diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Continue.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Continue.md new file mode 100644 index 000000000000..c3c18aa6a123 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Continue.md @@ -0,0 +1,138 @@ +--- +description: Describes how the `continue` statement immediately returns the program flow to the top of a program loop, a `switch` statement, or a `trap` statement. +Locale: en-US +ms.date: 06/04/2020 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_continue?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Continue +--- +# about_Continue + +## Short description + +Describes how the `continue` statement immediately returns the program flow +to the top of a program loop, a `switch` statement, or a `trap` statement. + +## Long description + +The `continue` statement provides a way to exit the current control block but +continue execution, rather than exit completely. The statement supports labels. +A label is a name you assign to a statement in a script. + +## Using continue in loops + +An unlabeled `continue` statement immediately returns the program flow to +the top of the innermost loop that is controlled by a `for`, `foreach`, `do`, +or `while` statement. The current iteration of the loop is terminated and the +loop continues with the next iteration. + +In the following example, program flow returns to the top of the `while` loop +if the `$ctr` variable is equal to 5. As a result, all the numbers between 1 +and 10 are displayed except for 5: + +```powershell +while ($ctr -lt 10) +{ + $ctr += 1 + if ($ctr -eq 5) + { + continue + } + + Write-Host -Object $ctr +} +``` + +When using a `for` loop, execution continues at the `` statement, +followed by the `` test. In the example below, an infinite loop +will not occur because the decrement of `$i` occurs after the `continue` +keyword. + +```powershell +# +for ($i = 0; $i -lt 10; $i++) +{ + Write-Host -Object $i + if ($i -eq 5) + { + continue + # Will not result in an infinite loop. + $i-- + } +} +``` + +### Using a labeled continue in a loop + +A labeled `continue` statement terminates execution of the iteration and +transfers control to the targeted enclosing iteration or `switch` statement +label. + +In the following example, the innermost `for` is terminated when `$condition` +is **True** and iteration continues with the second `for` loop at `labelB`. + +```powershell +:labelA for ($i = 1; $i -le 10; $i++) { + :labelB for ($j = 1; $j -le 10; $j++) { + :labelC for ($k = 1; $k -le 10; $k++) { + if ($condition) { + continue labelB + } else { + $condition = Update-Condition + } + } + } +} +``` + +## Using continue in a switch statement + +An unlabeled `continue` statement within a `switch` terminates execution of the +current `switch` iteration and transfers control to the top of the `switch` to get +the next input item. + +When there is a single input item `continue` exits the entire `switch` statement. +When the `switch` input is a collection, the `switch` tests each element of the +collection. The `continue` exits the current iteration and the `switch` continues +with the next element. + +```powershell +switch (1,2,3) { + 2 { continue } # moves on to the next element, 3 + default { $_ } +} +``` + +```Output +1 +3 +``` + +## Using continue in a trap statement + +If the final statement executed in the body a `trap` statement is `continue`, +the trapped error is silently ignored and execution continues with the +statement immediately following the one that caused `trap` to occur. + +## Do not use continue outside of a loop, switch, or trap + +When `continue` is used outside of a construct that directly supports it +(loops, `switch`, `trap`), PowerShell looks _up the call stack_ for an +enclosing construct. If it can't find an enclosing construct, the current +runspace is quietly terminated. + +This means that functions and scripts that inadvertently use a `continue` +outside of an enclosing construct that supports it, can inadvertently terminate +their _callers_. + +Using `continue` inside a pipeline, such as a `ForEach-Object` script block, +not only exits the pipeline, it potentially terminates the entire runspace. + +## See also + +- [about_Break](about_Break.md) +- [about_Comparison_Operators](about_Comparison_Operators.md) +- [about_For](about_For.md) +- [about_Throw](about_Throw.md) +- [about_Trap](about_Trap.md) +- [about_Try_Catch_Finally](about_Try_Catch_Finally.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Core_Commands.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Core_Commands.md new file mode 100644 index 000000000000..0d8f15847133 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Core_Commands.md @@ -0,0 +1,93 @@ +--- +description: Lists the cmdlets that are designed for use with PowerShell providers. +Locale: en-US +ms.date: 06/09/2017 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_core_commands?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Core_Commands +--- +# about_Core_Commands + +## Short description + +Lists the cmdlets that are designed for use with PowerShell providers. + +## Long description + +PowerShell includes a set of cmdlets that are specifically designed to manage +the items in the data stores that are exposed by PowerShell providers. +You can use these cmdlets in the same ways to manage all the different types +of data that the providers make available to you. For more information about +providers, type "get-help about_providers". + +For example, you can use the Get-ChildItem cmdlet to list the files in a file +system directory, the keys under a registry key, or the items that are exposed +by a provider that you write or download. + +The following is a list of the PowerShell cmdlets that are designed for use +with providers: + +ChildItem cmdlets + +- Get-ChildItem + +Content cmdlets + +- Add-Content +- Clear-Content +- Get-Content +- Set-Content + +Item cmdlets + +- Clear-Item +- Copy-Item +- Get-Item +- Invoke-Item +- Move-Item +- New-Item +- Remove-Item +- Rename-Item +- Set-Item + +ItemProperty cmdlets + +- Clear-ItemProperty +- Copy-ItemProperty +- Get-ItemProperty +- Move-ItemProperty +- New-ItemProperty +- Remove-ItemProperty +- Rename-ItemProperty +- Set-ItemProperty + +Location cmdlets + +- Get-Location +- Pop-Location +- Push-Location +- Set-Location + +Path cmdlets + +- Join-Path +- Convert-Path +- Split-Path +- Resolve-Path +- Test-Path + +PSDrive cmdlets + +- Get-PSDrive +- New-PSDrive +- Remove-PSDrive + +PSProvider cmdlets + +- Get-PSProvider + +For more information about a cmdlet, type `get-help `. + +## See also + +- [about_Providers](about_Providers.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Data_Files.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Data_Files.md new file mode 100644 index 000000000000..23d070337a2c --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Data_Files.md @@ -0,0 +1,77 @@ +--- +description: Describes how to use PowerShell data (.psd1) files. +Locale: en-US +ms.date: 01/19/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_data_files?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Data_Files +--- +# about_Data_Files + +## Short description + +PowerShell data files are used to store arbitrary data using PowerShell syntax. + +## Long description + +PowerShell data (`.psd1`) files can store arbitrary data in PowerShell syntax. +That data can be imported into variables in a PowerShell session. PowerShell +has three types of data files and provides a cmdlet to import each type. + +## Basic data files + +The `Import-PowerShellDataFile` cmdlet imports basic data files. The data in +the file must be contained in a hashtable. This format only supports constant +values. You can't use code or PowerShell expressions. + +## Module manifests + +Module manifests are PowerShell data files. The data in the file must be +contained in a hashtable. The structure of that hashtable only supports +specific key names related to PowerShell modules. + +The values assigned to the settings in the manifest file can be expressions +that are evaluated by PowerShell. This allows you to construct paths and +conditionally assign values based on variables. + +When you import a module using `Import-Module`, the manifest is evaluated in +`Restricted` language mode. `Restricted` mode limits the commands and variables +that can be used. + +For more information, see [about_Module_Manifests][03]. + +## Localized data + +The `Import-LocalizedData` cmdlet imports localized data files. During import, +the file is processed in `Constrained` language mode. `Constrained` mode limits +the commands and variables that can be used. + +For more information, see [about_Language_Modes][02]. + +Originally, localized data files were meant to be used to store string data that +could be translated into other languages. This allowed your scripts to import +the data to provide localized string output in other languages. However, you +aren't limited to storing string data and don't have to use the data for +localized output. + +The data in the file isn't limited to hashtables. It can be in any format +supported by the PowerShell syntax, such as `DATA` sections. + +For more information, see [about_Data_Sections][01]. + +## See also + +- [Import-LocalizedData][05] +- [Import-Module][04] +- [Import-PowerShellDataFile][06] +- [about_Data_Sections][01] +- [about_Language_Modes][02] +- [about_Module_Manifests][03] + + +[01]: about_Data_Sections.md +[02]: about_Language_Modes.md +[03]: about_Module_Manifests.md +[04]: xref:Microsoft.PowerShell.Core.Import-Module +[05]: xref:Microsoft.PowerShell.Utility.Import-LocalizedData +[06]: xref:Microsoft.PowerShell.Utility.Import-PowerShellDataFile diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Data_Sections.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Data_Sections.md new file mode 100644 index 000000000000..f8fb23b8c315 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Data_Sections.md @@ -0,0 +1,223 @@ +--- +description: Explains Data sections, which isolate text strings and other read-only data from script logic. +Locale: en-US +ms.date: 01/09/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_data_sections?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Data_Sections +--- +# about_Data_Sections + +## Short description + +Explains `DATA` sections, which isolate text strings and other read-only +data from script logic. + +## Long description + +Scripts that are designed for PowerShell can have one or more `DATA` sections +that contain only data. You can include one or more `DATA` sections in any +script, function, or advanced function. The content of the `DATA` section is +restricted to a specified subset of the PowerShell scripting language. + +Separating data from code logic makes it easier to identify and manage both +logic and data. It lets you have separate string resource files for text, such +as error messages and Help strings. It also isolates the code logic, which +facilitates security and validation tests. + +In PowerShell, you can use the `DATA` section to support script +internationalization. You can use `DATA` sections to make it easier to isolate, +locate, and process strings that can be translated into other languages. + +The `DATA` section was added in PowerShell 2.0 feature. + +### Syntax + +The syntax for a `DATA` section is as follows: + +```Syntax +DATA [] [-supportedCommand ] { + +} +``` + +The `DATA` keyword is required. It isn't case-sensitive. The permitted content +is limited to the following elements: + +- All PowerShell operators, except `-match` +- `If`, `Else`, and `ElseIf` statements +- The following automatic variables: `$PsCulture`, `$PsUICulture`, `$True`, + `$False`, and `$Null` +- Comments +- Pipelines +- Statements separated by semicolons (`;`) +- Literals, such as the following: + + ```powershell + a + 1 + 1,2,3 + "PowerShell 2.0" + @( "red", "green", "blue" ) + @{ a = 0x1; b = "great"; c ="script" } + [XML] @' +

Hello, World

+ '@ + ``` + +- Cmdlets that are permitted in a `DATA` section. By default, only the + `ConvertFrom-StringData` cmdlet is permitted. +- Cmdlets that you permit in a `DATA` section by using the `-SupportedCommand` + parameter. + +When you use the `ConvertFrom-StringData` cmdlet in a `DATA` section, you can +enclose the key-value pairs in single-quoted or double-quoted strings or in +single-quoted or double-quoted here-strings. However, strings that contain +variables and subexpressions must be enclosed in single-quoted strings or in +single-quoted here-strings so that the variables aren't expanded and the +subexpressions aren't executable. + +### -SupportedCommand + +The **SupportedCommand** parameter allows you to indicate that a cmdlet or +function generates only data. It's designed to allow users to include cmdlets +and functions in a `DATA` section that they have written or tested. + +The value of **SupportedCommand** is a comma-separated list of one or more +cmdlet or function names. + +For example, the following `DATA` section includes a user-written cmdlet, +`Format-Xml`, that formats data in an XML file: + +```powershell +DATA -supportedCommand Format-Xml +{ + Format-Xml -Strings string1, string2, string3 +} +``` + +### Using a `DATA` Section + +To use the content of a `DATA` section, assign it to a variable and use variable +notation to access the content. + +For example, the following `DATA` section contains a `ConvertFrom-StringData` +command that converts the here-string into a hash table. The hash table is +assigned to the `$TextMsgs` variable. + +The `$TextMsgs` variable isn't part of the `DATA` section. + +```powershell +$TextMsgs = DATA { + ConvertFrom-StringData -StringData @' +Text001 = Windows 7 +Text002 = Windows Server 2008 R2 +'@ +} +``` + +To access the keys and values in hash table in `$TextMsgs`, use the following +commands. + +```powershell +$TextMsgs.Text001 +$TextMsgs.Text002 +``` + +Alternately, you can put the variable name in the definition of the `DATA` +section. For example: + +```powershell +DATA TextMsgs { + ConvertFrom-StringData -StringData @' +Text001 = Windows 7 +Text002 = Windows Server 2008 R2 +'@ +} + +$TextMsgs +``` + +The result is the same as the previous example. + +```Output +Name Value +---- ----- +Text001 Windows 7 +Text002 Windows Server 2008 R2 +``` + +### Examples + +Simple data strings. + +```powershell +DATA { + "Thank you for using my PowerShell Organize.pst script." + "It is provided free of charge to the community." + "I appreciate your comments and feedback." +} +``` + +Strings that include permitted variables. + +```powershell +DATA { + if ($null) { + "To get help for this cmdlet, type get-help new-dictionary." + } +} +``` + +A single-quoted here-string that uses the `ConvertFrom-StringData` cmdlet: + +```powershell +DATA { + ConvertFrom-StringData -stringdata @' +Text001 = Windows 7 +Text002 = Windows Server 2008 R2 +'@ +} +``` + +A double-quoted here-string that uses the `ConvertFrom-StringData` cmdlet: + +```powershell +DATA { + ConvertFrom-StringData -stringdata @" +Msg1 = To start, press any key. +Msg2 = To exit, type "quit". +"@ +} +``` + +A data section that includes a user-written cmdlet that generates data: + +```powershell +DATA -supportedCommand Format-XML { + Format-Xml -strings string1, string2, string3 +} +``` + +## See also + +- [about_Automatic_Variables][01] +- [about_Comparison_Operators][02] +- [about_Hash_Tables][03] +- [about_If][04] +- [about_Operators][05] +- [about_Quoting_Rules][06] +- [about_Script_Internationalization][07] +- [ConvertFrom-StringData][08] +- [Import-LocalizedData][09] + + +[01]: about_Automatic_Variables.md +[02]: about_Comparison_Operators.md +[03]: about_Hash_Tables.md +[04]: about_If.md +[05]: about_Operators.md +[06]: about_Quoting_Rules.md +[07]: about_Script_Internationalization.md +[08]: xref:Microsoft.PowerShell.Utility.ConvertFrom-StringData +[09]: xref:Microsoft.PowerShell.Utility.Import-LocalizedData diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Debuggers.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Debuggers.md new file mode 100644 index 000000000000..425ee44d74ad --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Debuggers.md @@ -0,0 +1,711 @@ +--- +description: Describes the PowerShell debugger. +Locale: en-US +ms.date: 06/29/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_debuggers?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Debuggers +--- +# about_Debuggers + +## Short description + +Describes the PowerShell debugger. + +## Long description + +Debugging is the process of examining a script while it's running to identify +and correct errors in the script instructions. The PowerShell debugger can help +you examine and identify errors and inefficiencies in your scripts, functions, +commands, PowerShell Desired State Configuration (DSC) configurations, or +expressions. + +Starting in PowerShell 5.0, the PowerShell debugger has been updated to debug +scripts, functions, commands, configurations, or expressions that are running +in either the console or Windows PowerShell Integrated Scripting Environment +(ISE) on remote computers. + +> [!NOTE] +> The Windows PowerShell ISE only supports Windows PowerShell. For PowerShell 6 +> and higher you must use the Visual Studio Code with the extension for +> PowerShell. For more information, see +> [Debugging with Visual Studio Code][01]. + +## Debugger cmdlets + +The PowerShell debugger includes the following set of cmdlets: + +- `Set-PSBreakpoint`: Sets breakpoints on lines, variables, and commands. +- `Get-PSBreakpoint`: Gets breakpoints in the current session. +- `Disable-PSBreakpoint`: Turns off breakpoints in the current session. +- `Enable-PSBreakpoint`: Re-enables breakpoints in the current session. +- `Remove-PSBreakpoint`: Deletes breakpoints from the current session. +- `Get-PSCallStack`: Displays the current call stack. + +## Starting and stopping the debugger + +To start the debugger, set one or more breakpoints then run the script, +command, or function that you want to debug. + +When you reach a breakpoint, execution stops, and control is turned over to the +debugger. + +To stop the debugger, run the script, command, or function until it's complete. +Or, type `stop` or `t`. + +## Debugger commands + +When you use the debugger in the PowerShell console, use the following commands +to control the execution. In Windows PowerShell ISE, use commands on the Debug +menu. + +> [!NOTE] +> For information about how to use the debugger in other host applications, see +> the host application documentation. + +- `s`, `StepInto`: Executes the next statement and then stops. + +- `v`, `StepOver`: Executes the next statement, but skips functions and + invocations. The skipped statements are executed, but not stepped through. + +- `Ctrl+Break`: (Break All in ISE) Breaks into a running script within either + the PowerShell console, or Windows PowerShell ISE. Note that + Ctrl+Break in Windows PowerShell 2.0, 3.0, and 4.0 + closes the program. Break All works on both local and remote + interactively-running scripts. + +- `o`, `StepOut`: Steps out of the current function; up one level if nested. If + in the main body, it continues to the end or the next breakpoint. The skipped + statements are executed, but not stepped through. + +- `c`, `Continue`: Continues to run until the script is complete or until the + next breakpoint is reached. The skipped statements are executed, but not + stepped through. + +- `l`, `List`: Displays the part of the script that's executing. By default, it + displays the current line, five previous lines, and 10 subsequent lines. To + continue listing the script, press ENTER. + +- `l `, `List`: Displays 16 lines of the script beginning with the line + number specified by ``. + +- `l `, `List`: Displays `` lines of the script, beginning with the + line number specified by ``. + +- `q`, `Stop`, `Exit`: Stops executing the script, and exits the debugger. If + you are debugging a job by running the `Debug-Job` cmdlet, the `Exit` command + detaches the debugger, and allows the job to continue running. + +- `k`, `Get-PsCallStack`: Displays the current call stack. + +- ``: Repeats the last command if it was `Step` (`s`), `StepOver` (`v`), + or `List` (`l`). Otherwise, represents a submit action. + +- `?`, `h`: Displays the debugger command Help. + +To exit the debugger, you can use `Stop` (`q`). + +Starting in PowerShell 5.0, you can run the Exit command to exit a nested +debugging session that you started by running either `Debug-Job` or +`Debug-Runspace`. + +Using these debugger commands, you can run a script, stop on a point of +concern, examine the values of variables and the state of the system, and +continue running the script until you have identified a problem. + +> [!NOTE] +> If you step into a statement with a redirection operator, such as `>`, the +> PowerShell debugger steps over all remaining statements in the script. + +## Displaying the values of script variables + +While you are in the debugger, you can also enter commands, display the value +of variables, use cmdlets, and run scripts at the command line. You can display +the current value of all variables in the script that's being debugged, except +for the following automatic variables: + +```powershell +$_ +$Args +$Input +$MyInvocation +$PSBoundParameters +``` + +When you display the value of any of these variables, you get the value of that +variable for an internal pipeline the debugger uses, not the value of the +variable in the script. + +To display the value these variables for the script that's being debugged, add +lines to your script to save these values to a new variable. Set your +breakpoint after these new lines. Then you can display the value of the new +variable. + +For example, + +```powershell +$scriptArgs = $Args +$scriptname = $MyInvocation.PSCommandPath +``` + +## The debugger environment + +When you reach a breakpoint, you enter the debugger environment. The command +prompt changes so that it begins with "[DBG]:". Also, in some host +applications, such as the PowerShell console, a nested prompt opens for +debugging. You can detect the nested prompt by the repeating greater-than +characters (ASCII 62) that appear at the command prompt. + +For more information about customizing the prompt, see [about_Prompts][02]. + +You can find the nesting level by using the `$NestedPromptLevel` automatic +variable. The automatic variable, `$PSDebugContext`, is defined in the local +scope. You can use the presence of the `$PSDebugContext` variable to determine +whether you are running within the debugger. + +For example: + +```powershell +if ($PSDebugContext) {"Debugging"} else {"Not Debugging"} +``` + +You can use the value of the `$PSDebugContext` variable in your debugging. + +``` +[DBG]: PS>>> $PSDebugContext.InvocationInfo + +Name CommandLineParameters UnboundArguments Location +---- --------------------- ---------------- -------- += {} {} C:\ps-test\vote.ps1 (1) +``` + +## Debugging and scope + +Breaking into the debugger doesn't change the scope in which you are operating, +but when you reach a breakpoint in a script, you move into the script scope. +The script scope is a child of the scope in which you ran the debugger. + +To find the variables and aliases that are defined in the script scope, use the +Scope parameter of the `Get-Alias` or `Get-Variable` cmdlets. + +For example, the following command gets the variables in the local (script) +scope: + +```powershell +Get-Variable -scope 0 +``` + +This is a useful way to see only the variables that you defined in the script +and that you defined while debugging. + +## Debugging at the command line + +When you set a variable breakpoint or a command breakpoint, you can set the +breakpoint only in a script file. However, by default, the breakpoint is set on +anything that runs in the current session. + +For example, if you set a breakpoint on the `$name` variable, the debugger +breaks on any `$name` variable in any script, command, function, script cmdlet +or expression that you run until you disable or remove the breakpoint. + +This allows you to debug your scripts in a more realistic context in which they +might be affected by functions, variables, and other scripts in the session and +in the user's profile. + +Line breakpoints are specific to script files, so they're set only in script +files. + +## Debugging functions + +When you set a breakpoint on a function that has `begin`, `process`, and `end` +sections, the debugger breaks at the first line of each section. + +For example: + +```powershell +function test-cmdlet { + begin { + write-output "Begin" + } + process { + write-output "Process" + } + end { + write-output "End" + } +} + +C:\PS> Set-PSBreakpoint -command test-cmdlet + +C:\PS> test-cmdlet + +Begin +Entering debug mode. Use h or ? for help. + +Hit Command breakpoint on 'prompt:test-cmdlet' + +test-cmdlet + +[DBG]: C:\PS> c +Process +Entering debug mode. Use h or ? for help. + +Hit Command breakpoint on 'prompt:test-cmdlet' + +test-cmdlet + +[DBG]: C:\PS> c +End +Entering debug mode. Use h or ? for help. + +Hit Command breakpoint on 'prompt:test-cmdlet' + +test-cmdlet + +[DBG]: C:\PS> +``` + +## Debugging remote scripts + +You can run `Enter-PSSession` to start an interactive remote PowerShell session +in which you can set breakpoints and debug script files and commands on the +remote computer. `Enter-PSSession` lets you reconnect a disconnected session +that's running a script or command on a remote computer. If the running script +hits a breakpoint, your client session automatically starts the debugger. If +the disconnected session that's running a script has already hit a breakpoint, +`Enter-PSSession` automatically starts the command-line debugger, when you +reconnect to the session. + +The following example shows how this works. Breakpoints have been set at lines +6, 11, 22, and 25 of the script. When the debugger starts, there are two +identifying changes to the prompt: + +- The name of the computer on which the session is running +- The DBG prompt that lets you know you are in debugging mode + +```powershell +Enter-PSSession -Cn localhost +[localhost]: PS C:\psscripts> Set-PSBreakpoint .\ttest19.ps1 6,11,22,25 + +ID Script Line Command Variable Action +-- ------ ---- ------- -------- ------ +0 ttest19.ps1 6 +1 ttest19.ps1 11 +2 ttest19.ps1 22 +3 ttest19.ps1 25 + +[localhost]: PS C:\psscripts> .\ttest19.ps1 +Hit Line breakpoint on 'C:\psscripts\ttest19.ps1:11' + +At C:\psscripts\ttest19.ps1:11 char:1 ++ $winRMName = "WinRM" +# + ~ + +[localhost]: [DBG]: PS C:\psscripts>> list + +6: 1..5 | foreach { sleep 1; Write-Output "hello2day $_" } +7: } +# 8: + +9: $count = 10 +10: $psName = "PowerShell" +11:* $winRMName = "WinRM" +12: $myVar = 102 +# 13: + +14: for ($i=0; $i -lt $count; $i++) +15: { +16: sleep 1 +17: Write-Output "Loop iteration is: $i" +18: Write-Output "MyVar is $myVar" +# 19: + +20: hello2day +# 21: + + +[localhost]: [DBG]: PS C:\psscripts>> stepover +At C:\psscripts\ttest19.ps1:12 char:1 ++ $myVar = 102 +# + ~ + +[localhost]: [DBG]: PS C:\psscripts>> quit +[localhost]: PS C:\psscripts> Exit-PSSession +PS C:\psscripts> +``` + +## Examples + +This test script detects the version of PowerShell and displays a +version-appropriate message. It includes a function, a function call, and a +variable. + +The following command displays the contents of the test script file: + +```powershell +PS C:\PS-test> Get-Content test.ps1 + +function psversion { + "PowerShell " + $PSVersionTable.PSVersion + if ($PSVersionTable.PSVersion.Major -lt 7) { + "Upgrade to PowerShell 7!" + } + else { + "Have you run a background job today (start-job)?" + } +} + +$scriptName = $MyInvocation.PSCommandPath +psversion +"Done $scriptName." +``` + +To start, set a breakpoint at a point of interest in the script, such as a +line, command, variable, or function. + +Start by creating a line breakpoint on the first line of the Test.ps1 script in +the current directory. + +```powershell +PS C:\ps-test> Set-PSBreakpoint -line 1 -script test.ps1 +``` + +The command returns a **System.Management.Automation.LineBreakpoint** object. + +```Output +Column : 0 +Line : 1 +Action : +Enabled : True +HitCount : 0 +Id : 0 +Script : C:\ps-test\test.ps1 +ScriptName : C:\ps-test\test.ps1 +``` + +Now, start the script. + +```powershell +PS C:\ps-test> .\test.ps1 +``` + +When the script reaches the first breakpoint, the breakpoint message indicates +that the debugger is active. It describes the breakpoint and previews the first +line of the script, which is a function declaration. The command prompt also +changes to indicate that the debugger has control. + +The preview line includes the script name and the line number of the previewed +command. + +```powershell +Entering debug mode. Use h or ? for help. + +Hit Line breakpoint on 'C:\ps-test\test.ps1:1' + +test.ps1:1 function psversion { +DBG> +``` + +Use the Step command (s) to execute the first statement in the script and to +preview the next statement. The next statement uses the `$MyInvocation` +automatic variable to set the value of the `$scriptName` variable to the path +and file name of the script file. + +```powershell +DBG> s +test.ps1:11 $scriptName = $MyInvocation.PSCommandPath +``` + +At this point, the `$scriptName` variable isn't populated, but you can verify +the value of the variable by displaying its value. In this case, the value is +`$null`. + +```powershell +DBG> $scriptname +DBG> +``` + +Use another `Step` command (`s`) to execute the current statement and to +preview the next statement in the script. The next statement calls the +`psversion` function. + +```powershell +DBG> s +test.ps1:12 psversion +``` + +At this point, the `$scriptName` variable is populated, but you verify the +value of the variable by displaying its value. In this case, the value is set +to the script path. + +```powershell +DBG> $scriptName +C:\ps-test\test.ps1 +``` + +Use another Step command to execute the function call. Press ENTER, or type "s" +for Step. + +```powershell +DBG> s +test.ps1:2 "PowerShell " + $PSVersionTable.PSVersion +``` + +The debug message includes a preview of the statement in the function. To +execute this statement and to preview the next statement in the function, you +can use a `Step` command. But, in this case, use a StepOut command (o). It +completes the execution of the function (unless it reaches a breakpoint) and +steps to the next statement in the script. + +```powershell +DBG> o +Windows PowerShell 2.0 +Have you run a background job today (start-job)? +test.ps1:13 "Done $scriptName" +``` + +Because we're on the last statement in the script, the Step, StepOut, and +Continue commands have the same effect. In this case, use StepOut (o). + +```powershell +Done C:\ps-test\test.ps1 +PS C:\ps-test> +``` + +The StepOut command executes the last command. The standard command prompt +indicates that the debugger has exited and returned control to the command +processor. + +Now, run the debugger again. First, to delete the current breakpoint, use the +`Get-PsBreakpoint` and `Remove-PsBreakpoint` cmdlets. (If you think you might +reuse the breakpoint, use the `Disable-PsBreakpoint` cmdlet instead of +`Remove-PsBreakpoint`.) + +```powershell +PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint +``` + +You can abbreviate this command as: + +```powershell +PS C:\ps-test> gbp | rbp +``` + +Or, run the command by writing a function, such as the following +function: + +```powershell +function delbr { gbp | rbp } +``` + +Now, create a breakpoint on the `$scriptname` variable. + +```powershell +PS C:\ps-test> Set-PSBreakpoint -variable scriptname -script test.ps1 +``` + +You can abbreviate the command as: + +```powershell +PS C:\ps-test> sbp -v scriptname -s test.ps1 +``` + +Now, start the script. The script reaches the variable breakpoint. The default +mode is Write, so execution stops just before the statement that changes the +value of the variable. + +```powershell +PS C:\ps-test> .\test.ps1 +Hit Variable breakpoint on 'C:\ps-test\test.ps1:$scriptName' +(Write access) + +test.ps1:11 $scriptName = $MyInvocation.PSCommandPath +DBG> +``` + +Display the current value of the `$scriptName` variable, which is `$null`. + +```powershell +DBG> $scriptName +DBG> +``` + +Use a `Step` command (`s`) to execute the statement that populates the +variable. Then, display the new value of the `$scriptName` variable. + +```powershell +DBG> $scriptName +C:\ps-test\test.ps1 +``` + +Use a Step command (s) to preview the next statement in the script. + +```powershell +DBG> s +test.ps1:12 psversion +``` + +The next statement is a call to the `psversion` function. To skip the function +but still execute it, use a `StepOver` command (`v`). If you are already in the +function when you use `StepOver`, it isn't effective. The function call is +displayed, but it isn't executed. + +```powershell +DBG> v +Windows PowerShell 2.0 +Have you run a background job today (start-job)? +test.ps1:13 "Done $scriptName" +``` + +The `StepOver` command executes the function, and it previews the next statement +in the script, which prints the final line. + +Use a `Stop` command (`t`) to exit the debugger. The command prompt reverts to +the standard command prompt. + +```powershell +C:\ps-test> +``` + +To delete the breakpoints, use the `Get-PsBreakpoint` and `Remove-PsBreakpoint` +cmdlets. + +```powershell +PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint +``` + +Create a new command breakpoint on the `psversion` function. + +```powershell +PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1 +``` + +You can abbreviate this command to: + +```powershell +PS C:\ps-test> sbp -c psversion -s test.ps1 +``` + +Now, run the script. + +```powershell +PS C:\ps-test> .\test.ps1 +Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion' + +test.ps1:12 psversion +DBG> +``` + +The script reaches the breakpoint at the function call. At this point, the +function hasn't yet been called. This gives you the opportunity to use the +Action parameter of `Set-PSBreakpoint` to set conditions for the execution of +the breakpoint or to perform preparatory or diagnostic tasks, such as starting +a log or invoking a diagnostic or security script. + +To set an action, use a Continue command (c) to exit the script, and a +`Remove-PsBreakpoint` command to delete the current breakpoint. (Breakpoints +are read-only, so you can't add an action to the current breakpoint.) + +```powershell +DBG> c +Windows PowerShell 2.0 +Have you run a background job today (start-job)? +Done C:\ps-test\test.ps1 + +PS C:\ps-test> Get-PSBreakpoint| Remove-PSBreakpoint +PS C:\ps-test> +``` + +Now, create a new command breakpoint with an action. The following command sets +a command breakpoint with an action that logs the value of the `$scriptName` +variable when the function is called. Because the `break` keyword isn't used in +the action, execution doesn't stop. The backtick (`` ` ``) is the +line-continuation character. + +```powershell +PS C:\ps-test> Set-PSBreakpoint -command psversion -script test.ps1 ` +-action { add-content "The value of `$scriptName is $scriptName." ` +-path action.log} +``` + +You can also add actions that set conditions for the breakpoint. In the +following command, the command breakpoint is executed only if the execution +policy is set to RemoteSigned, the most restrictive policy that still permits +you to run scripts. + +```powershell +PS C:\ps-test> Set-PSBreakpoint -script test.ps1 -command psversion ` +-action { if ((Get-ExecutionPolicy) -eq "RemoteSigned") { break }} +``` + +The `break` keyword in the action directs the debugger to execute the +breakpoint. You can also use the `continue` keyword to direct the debugger to +execute without breaking. Because the default keyword is `continue`, you must +specify `break` to stop execution. + +Now, run the script. + +```powershell +PS C:\ps-test> .\test.ps1 +Hit Command breakpoint on 'C:\ps-test\test.ps1:psversion' + +test.ps1:12 psversion +``` + +Because the execution policy is set to **RemoteSigned**, execution stops at the +function call. + +At this point, you might want to check the call stack. Use the +`Get-PsCallStack` cmdlet or the `Get-PsCallStack` debugger command (`k`). The +following command gets the current call stack. + +```powershell +DBG> k +2: prompt +1: .\test.ps1: $args=[] +0: prompt: $args=[] +``` + +This example demonstrates just a few of the many ways to use the PowerShell +debugger. + +## Other Debugging Features in PowerShell + +In addition to the PowerShell debugger, PowerShell includes several other +features that you can use to debug scripts and functions. + +- The `Set-PSDebug` cmdlet offers very basic script debugging features, + including stepping and tracing. + +- Use the `Set-StrictMode` cmdlet to detect references to uninitialized + variables, to references to non-existent properties of an object, and to + function syntax that isn't valid. + +- Add diagnostic statements to a script, such as statements that display the + value of variables, statements that read input from the command line, or + statements that report the current instruction. Use the cmdlets that contain + the Write verb for this task, such as `Write-Host`, `Write-Debug`, + `Write-Warning`, and `Write-Verbose`. + +## See also + +- [Disable-PSBreakpoint][05] +- [Enable-PSBreakpoint][06] +- [Get-PSBreakpoint][07] +- [Remove-PSBreakpoint][09] +- [Set-PSBreakpoint][10] +- [Get-PSCallStack][08] +- [Write-Debug][11] +- [Write-Verbose][12] + + +[01]: /powershell/scripting/dev-cross-plat/vscode/using-vscode#debugging-with-visual-studio-code +[02]: about_prompts.md +[05]: xref:Microsoft.PowerShell.Utility.Disable-PSBreakpoint +[06]: xref:Microsoft.PowerShell.Utility.Enable-PSBreakpoint +[07]: xref:Microsoft.PowerShell.Utility.Get-PSBreakpoint +[08]: xref:Microsoft.PowerShell.Utility.Get-PSCallStack +[09]: xref:Microsoft.PowerShell.Utility.Remove-PSBreakpoint +[10]: xref:Microsoft.PowerShell.Utility.Set-PSBreakpoint +[11]: xref:Microsoft.PowerShell.Utility.Write-Debug +[12]: xref:Microsoft.PowerShell.Utility.Write-Verbose diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Do.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Do.md new file mode 100644 index 000000000000..419c6f870152 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Do.md @@ -0,0 +1,95 @@ +--- +description: Runs a statement list one or more times, subject to a While or Until condition. +Locale: en-US +ms.date: 06/10/2021 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_do?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Do +--- +# about_Do + +## Short description + +Runs a statement list one or more times, subject to a `While` or `Until` +condition. + +## Long description + +The `Do` keyword works with the `While` keyword or the `Until` keyword to run +the statements in a script block, subject to a condition. Unlike the related +`While` loop, the script block in a `Do` loop always runs at least once. + +A **Do-While** loop is a variety of the `While` loop. In a **Do-While** loop, +the condition is evaluated after the script block has run. As in a While loop, +the script block is repeated as long as the condition evaluates to true. + +Like a **Do-While** loop, a **Do-Until** loop always runs at least once +before the condition is evaluated. However, the script block runs only +while the condition is false. + +The `Continue` and `Break` flow control keywords can be used in a **Do-While** +loop or in a **Do-Until** loop. + +### Syntax + +The following shows the syntax of the **Do-While** statement: + +```powershell +do {} while () +``` + +The following shows the syntax of the **Do-Until** statement: + +```powershell +do {} until () +``` + +The statement list contains one or more statements that run each time the loop +is entered or repeated. + +The condition portion of the statement resolves to true or false. For more +information about how booleans are evaluated, see +[about_Booleans](about_Booleans.md). + +### Example + +The following example of a `Do` statement counts the items in an array until it +reaches an item with a value of 0. + +```powershell +PS> $x = 1,2,78,0 +PS> do { $count++; $a++; } while ($x[$a] -ne 0) +PS> $count +3 +``` + +The following example uses the `Until` keyword. Notice that the not equal to +operator (`-ne`) is replaced by the equal to operator (`-eq`). + +```powershell +PS> $x = 1,2,78,0 +PS> do { $count++; $a++; } until ($x[$a] -eq 0) +PS> $count +3 +``` + +The following example writes all the values of an array, skipping any value +that is less than zero. + +```powershell +do { + if ($x[$a] -lt 0) { continue } + Write-Host $x[$a] +} +while (++$a -lt 10) +``` + +## See also + +- [about_Booleans](about_Booleans.md) +- [about_Break](about_Break.md) +- [about_Continue](about_Continue.md) +- [about_Operators](about_Operators.md) +- [about_Assignment_Operators](about_Assignment_Operators.md) +- [about_Comparison_Operators](about_Comparison_Operators.md) +- [about_While](about_While.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Enum.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Enum.md new file mode 100644 index 000000000000..8529e78914e1 --- /dev/null +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Enum.md @@ -0,0 +1,1240 @@ +--- +description: The `enum` statement is used to declare an enumeration. An enumeration is a distinct type that consists of a set of named labels called the enumerator list. +Locale: en-US +ms.date: 11/20/2023 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_enum?view=powershell-7.6&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Enum +--- +# about_Enum + +## Short description + +The `enum` statement declares an enumeration. An enumeration is a +distinct type that consists of a set of named labels called the enumerator +list. + +## Long description + +The `enum` statement allows you to create a strongly typed set of labels. You +can use that enumeration in the code without having to parse or check for +spelling errors. + +Enumerations are internally represented as integral value types with a starting +value of zero. By default, PowerShell enumerations use **System.Int32** +(`[int]`) as the underlying type. By default, PowerShell assigns the first +label in the list the value zero. By default, PowerShell assigns the remaining +labels with consecutive integers. + +In the definition, you can give labels any integer value. Labels with no value +assigned take the next integer value. + +## Syntax + +Enumerations use the following syntaxes: + +### Integer enumeration definition syntax + +```Syntax +[[]...] enum { +