diff --git a/reference/7.7/CimCmdlets/CimCmdlets.md b/reference/7.7/CimCmdlets/CimCmdlets.md new file mode 100644 index 00000000000..11290d63944 --- /dev/null +++ b/reference/7.7/CimCmdlets/CimCmdlets.md @@ -0,0 +1,69 @@ +--- +Download Help Link: https://aka.ms/powershell77-help +Help Version: 7.7.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 + +### [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. + +### [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.7/CimCmdlets/Get-CimAssociatedInstance.md b/reference/7.7/CimCmdlets/Get-CimAssociatedInstance.md new file mode 100644 index 00000000000..be0e494461a --- /dev/null +++ b/reference/7.7/CimCmdlets/Get-CimAssociatedInstance.md @@ -0,0 +1,339 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - gcai +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.7/CimCmdlets/Get-CimClass.md b/reference/7.7/CimCmdlets/Get-CimClass.md new file mode 100644 index 00000000000..01839fd7712 --- /dev/null +++ b/reference/7.7/CimCmdlets/Get-CimClass.md @@ -0,0 +1,323 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - gcls +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.7/CimCmdlets/Get-CimInstance.md b/reference/7.7/CimCmdlets/Get-CimInstance.md new file mode 100644 index 00000000000..7181bb36163 --- /dev/null +++ b/reference/7.7/CimCmdlets/Get-CimInstance.md @@ -0,0 +1,555 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 01/16/2026 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/get-ciminstance?view=powershell-7.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - gcim +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 +$instance = @{ + ClassName = 'Win32_Process' + Namespace = 'root/CIMV2' + Properties = @{ + Handle = 0 + } + Key = 'Handle' + ClientOnly = $true +} +$x = New-CimInstance @instance +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) + +[about_WQL](../Microsoft.PowerShell.Core/About/about_WQL.md) diff --git a/reference/7.7/CimCmdlets/Get-CimSession.md b/reference/7.7/CimCmdlets/Get-CimSession.md new file mode 100644 index 00000000000..3b76506fd12 --- /dev/null +++ b/reference/7.7/CimCmdlets/Get-CimSession.md @@ -0,0 +1,267 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - gcms +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.7/CimCmdlets/Invoke-CimMethod.md b/reference/7.7/CimCmdlets/Invoke-CimMethod.md new file mode 100644 index 00000000000..0cd93b3b722 --- /dev/null +++ b/reference/7.7/CimCmdlets/Invoke-CimMethod.md @@ -0,0 +1,495 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 01/16/2026 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/invoke-cimmethod?view=powershell-7.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - icim +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 +$method = @{ + Query = 'select * from Win32_Process where name like "notepad%"' + MethodName = "Terminate" +} +Invoke-CimMethod @method +``` + +### 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 **Foo** method by passing a **CimClass** object +to `Invoke-CimMethod`. + +```powershell +$c = Get-CimClass -ClassName Win32_Process +Invoke-CimMethod -CimClass $c -MethodName "Foo" -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](https://go.microsoft.com/fwlink/?LinkID=113216). + +## 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) + +[about_WQL](../Microsoft.PowerShell.Core/About/about_WQL.md) diff --git a/reference/7.7/CimCmdlets/New-CimInstance.md b/reference/7.7/CimCmdlets/New-CimInstance.md new file mode 100644 index 00000000000..3d102c67e59 --- /dev/null +++ b/reference/7.7/CimCmdlets/New-CimInstance.md @@ -0,0 +1,444 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - ncim +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 +$prop = @{ + Name = "testvar" + VariableValue = "testvalue" + UserName = "domain\user" +} +New-CimInstance -ClassName Win32_Environment -Property $prop +``` + +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 +$prop = @{ + Name = "testvar" + VariableValue = "testvalue" + UserName = "Contoso\User1" +} +New-CimInstance -CimClass $class -Property $prop +``` + +### 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 +$instance = @{ + ClassName = 'Win32_Process' + Property = @{ + Handle = 0 + } + Key = 'Handle' + ClientOnly = $true +} +$a = New-CimInstance @instance + +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](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 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.7/CimCmdlets/New-CimSession.md b/reference/7.7/CimCmdlets/New-CimSession.md new file mode 100644 index 00000000000..64a0b7f52f0 --- /dev/null +++ b/reference/7.7/CimCmdlets/New-CimSession.md @@ -0,0 +1,393 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - ncms +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](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 `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.7/CimCmdlets/New-CimSessionOption.md b/reference/7.7/CimCmdlets/New-CimSessionOption.md new file mode 100644 index 00000000000..86614d004d5 --- /dev/null +++ b/reference/7.7/CimCmdlets/New-CimSessionOption.md @@ -0,0 +1,510 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - ncso +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 +$option = @{ + ProxyAuthentication = 'Kerberos' + ProxyCredential = $cred + SkipCACheck = $true + SkipCNCheck = $true + UseSsl = $true +} +New-CimSessionOption @option +``` + +### 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.7/CimCmdlets/Register-CimIndicationEvent.md b/reference/7.7/CimCmdlets/Register-CimIndicationEvent.md new file mode 100644 index 00000000000..9cd8a0e4054 --- /dev/null +++ b/reference/7.7/CimCmdlets/Register-CimIndicationEvent.md @@ -0,0 +1,431 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 01/18/2026 +no-loc: [-Forward] +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/register-cimindicationevent?view=powershell-7.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: +- rcie +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 +$event = @{ + ClassName = 'Win32_ProcessStartTrace' + SourceIdentifier = 'ProcessStarted' +} +Register-CimIndicationEvent @event +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 +scriptblock 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" +} +$event = @{ + ClassName = 'Win32_ProcessStartTrace' + SourceIdentifier = 'ProcessStarted' + Action = $action +} +Register-CimIndicationEvent @event +``` + +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 +$event = @{ + ClassName = 'Win32_ProcessStartTrace' + SourceIdentifier = 'ProcessStarted' + ComputerName = 'Server01' +} +Register-CimIndicationEvent @event +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 scriptblock. + +The scriptblock specified with **Action** can include the `$Event`, `$EventSubscriber`, `$Sender`, +`$SourceEventArgs`, and `$SourceArgs` automatic variables, which provide information about the event +to the **Action** scriptblock. 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) + +[about_WQL](../Microsoft.PowerShell.Core/About/about_WQL.md) + diff --git a/reference/7.7/CimCmdlets/Remove-CimInstance.md b/reference/7.7/CimCmdlets/Remove-CimInstance.md new file mode 100644 index 00000000000..a44c5a05d2a --- /dev/null +++ b/reference/7.7/CimCmdlets/Remove-CimInstance.md @@ -0,0 +1,340 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 01/16/2026 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/remove-ciminstance?view=powershell-7.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - rcim +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) + +[about_WQL](../Microsoft.PowerShell.Core/About/about_WQL.md) diff --git a/reference/7.7/CimCmdlets/Remove-CimSession.md b/reference/7.7/CimCmdlets/Remove-CimSession.md new file mode 100644 index 00000000000..26318c9c6e7 --- /dev/null +++ b/reference/7.7/CimCmdlets/Remove-CimSession.md @@ -0,0 +1,250 @@ +--- +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - rcms +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.7/CimCmdlets/Set-CimInstance.md b/reference/7.7/CimCmdlets/Set-CimInstance.md new file mode 100644 index 00000000000..b901028777e --- /dev/null +++ b/reference/7.7/CimCmdlets/Set-CimInstance.md @@ -0,0 +1,458 @@ +--- +external help file: Microsoft.Management.Infrastructure.CimCmdlets.dll-Help.xml +Locale: en-US +Module Name: CimCmdlets +ms.date: 01/16/2026 +online version: https://learn.microsoft.com/powershell/module/cimcmdlets/set-ciminstance?view=powershell-7.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +aliases: + - scim +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 +$instance = @ { + Query = 'Select * from Win32_Environment where name LIKE "testvar%"' + Property = @{VariableValue="abcd"} +} +Set-CimInstance @instance +``` + +### 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 +$instance = @{ + Query = 'Select * from Win32_Environment where name LIKE "testvar%"' + Property = @{VariableValue="abcd"} + WhatIf = $true +} +Set-CimInstance @instance +``` + +### 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 +$instance = @{ + Query = 'Select * from Win32_Environment where name LIKE "testvar%"' + Property = @{VariableValue="abcd"} + Confirm = $true +} +Set-CimInstance @instance +``` + +### 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 +$instance = @{ + ClassName = 'Win32_Environment' + Property = @{ + Name="testvar" + UserName="domain\user" + } + Key = 'Name', 'UserName' + ClientOnly = $true +} +$x = New-CimInstance @instance +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](https://go.microsoft.com/fwlink/?LinkID=113216). + +## 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) + +[about_WQL](../Microsoft.PowerShell.Core/About/about_WQL.md) diff --git a/reference/7.7/Microsoft.PowerShell.Archive/Compress-Archive.md b/reference/7.7/Microsoft.PowerShell.Archive/Compress-Archive.md new file mode 100644 index 00000000000..70f41b1a863 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Archive/Compress-Archive.md @@ -0,0 +1,467 @@ +--- +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.7&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.7/Microsoft.PowerShell.Archive/Expand-Archive.md b/reference/7.7/Microsoft.PowerShell.Archive/Expand-Archive.md new file mode 100644 index 00000000000..144708394f7 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Archive/Expand-Archive.md @@ -0,0 +1,220 @@ +--- +external help file: Microsoft.PowerShell.Archive-help.xml +Locale: en-US +Module Name: Microsoft.PowerShell.Archive +ms.date: 04/01/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-7.7&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. + +This cmdlet only works with zip archives, which typically have the file extension `.zip`. + +The `Expand-Archive` cmdlet uses the **System.IO.Compression.ZipArchive** API to compress files. +The API limits the maximum file size to 2GB. The .NET API works with files that conform to the +official ZIP file format specification by PKWARE Inc. For more information, see +[System.IO.Compression.ZipArchive](xref:System.IO.Compression.ZipArchive). + +## 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.7/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.md b/reference/7.7/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.md new file mode 100644 index 00000000000..4bb5aefa54f --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.md @@ -0,0 +1,28 @@ +--- +Download Help Link: https://aka.ms/powershell77-help +Help Version: 7.7.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.7/Microsoft.PowerShell.Core/About/.markdownlint.yaml b/reference/7.7/Microsoft.PowerShell.Core/About/.markdownlint.yaml new file mode 100644 index 00000000000..cfd0d7fc37b --- /dev/null +++ b/reference/7.7/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.7/Microsoft.PowerShell.Core/About/About.md b/reference/7.7/Microsoft.PowerShell.Core/About/About.md new file mode 100644 index 00000000000..153a3764cb7 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/About.md @@ -0,0 +1,663 @@ +--- +description: About topics cover a range of concepts about PowerShell. +Help Version: 7.7.0.0 +Locale: en-US +ms.date: 01/18/2026 +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_Error_Handling](about_Error_Handling.md) + +Describes the three categories of PowerShell errors — non-terminating, +statement-terminating, and script-terminating — and explains how error +action preferences, `try/catch/trap`, and error state variables control +error handling behavior. + +### [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 the 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 scriptblock. + +### [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 scriptblock is and explains how to use scriptblocks 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 script-terminating error by +default. + +### [about_Trap](about_Trap.md) + +Describes a keyword that handles statement-terminating and script-terminating +errors. + +### [about_Try_Catch_Finally](about_Try_Catch_Finally.md) + +Describes how to use the `try`, `catch`, and `finally` blocks to handle +statement-terminating and script-terminating errors. + +### [about_Type_Accelerators](about_Type_Accelerators.md) + +Describes the Type accelerators available for .NET types. + +### [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.7/Microsoft.PowerShell.Core/About/about_ANSI_Terminals.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_ANSI_Terminals.md new file mode 100644 index 00000000000..e1fe530b454 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_ANSI_Terminals.md @@ -0,0 +1,398 @@ +--- +description: Describes the features of PowerShell that use ANSI escape sequences and the terminal hosts that support them. +Locale: en-US +ms.date: 12/09/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_ansi_terminals?view=powershell-7.7&WT.mc_id=ps-gethelp +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 predefines colors for archive and + PowerShell file extensions. + + The following example shows how to change the colors for various `FileInfo` + settings and specific file extensions. The colors are chosen to work well + on a light terminal background. + + ```powershell + $PSStyle.FileInfo.Directory = $PSStyle.Background.FromRgb(0x2f6aff) + + $PSStyle.Foreground.BrightWhite + $PSStyle.FileInfo.SymbolicLink = $PSStyle.Foreground.Cyan + $PSStyle.FileInfo.Executable = $PSStyle.Foreground.BrightMagenta + $PSStyle.FileInfo.Extension['.ps1'] = $PSStyle.Foreground.Cyan + $PSStyle.FileInfo.Extension['.ps1xml'] = $PSStyle.Foreground.Cyan + $PSStyle.FileInfo.Extension['.psd1'] = $PSStyle.Foreground.Cyan + $PSStyle.FileInfo.Extension['.psm1'] = $PSStyle.Foreground.Cyan + ``` + +## 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` +- `xterm` - 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.7/Microsoft.PowerShell.Core/About/about_Alias_Provider.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Alias_Provider.md new file mode 100644 index 00000000000..e014895a153 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Alias_Provider.md @@ -0,0 +1,337 @@ +--- +description: The Alias provider enables access to the PowerShell aliases and the values that they represent. +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.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Alias_Provider +--- +# about_Alias_Provider + +## Provider name + +Alias + +## Drives + +`Alias:` + +## Capabilities + +**ShouldProcess** + +## 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][01] +- [Set-Location][02] +- [Get-Item][03] +- [New-Item][04] +- [Remove-Item][05] +- [Clear-Item][06] + +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][07] +- [Get-Alias][08] +- [Import-Alias][09] +- [New-Alias][10] +- [Set-Alias][11] + +## Types exposed by this provider + +Each alias is an instance of the [System.Management.Automation.AliasInfo][12] +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][13], `cd` is an alias for +> [Set-Location][02] and `pwd` is an alias for [Get-Location][01]. + +### 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][04] +- [Set-Item][14] + +## 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][15] command in a file system drive or use the `-Path` parameter of +[Get-Help][15] to specify a file system drive. + +```powershell +Get-Help Get-ChildItem +``` + +```powershell +Get-Help Get-ChildItem -Path Alias: +``` + +## See also + +- [about_Aliases][16] +- [about_Providers][17] + + +[01]: xref:Microsoft.PowerShell.Management.Get-Location +[02]: xref:Microsoft.PowerShell.Management.Set-Location +[03]: xref:Microsoft.PowerShell.Management.Get-Item +[04]: xref:Microsoft.PowerShell.Management.New-Item +[05]: xref:Microsoft.PowerShell.Management.Remove-Item +[06]: xref:Microsoft.PowerShell.Management.Clear-Item +[07]: xref:Microsoft.PowerShell.Utility.Export-Alias +[08]: xref:Microsoft.PowerShell.Utility.Get-Alias +[09]: xref:Microsoft.PowerShell.Utility.Import-Alias +[10]: xref:Microsoft.PowerShell.Utility.New-Alias +[11]: xref:Microsoft.PowerShell.Utility.Set-Alias +[12]: /dotnet/api/system.management.automation.aliasinfo +[13]: xref:Microsoft.PowerShell.Management.Get-ChildItem +[14]: xref:Microsoft.PowerShell.Management.Set-Item +[15]: xref:Microsoft.PowerShell.Core.Get-Help +[16]: about_Aliases.md +[17]: about_Providers.md diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Aliases.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Aliases.md new file mode 100644 index 00000000000..76895033101 --- /dev/null +++ b/reference/7.7/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.7&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.7/Microsoft.PowerShell.Core/About/about_Arithmetic_Operators.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Arithmetic_Operators.md new file mode 100644 index 00000000000..fc9a01b5387 --- /dev/null +++ b/reference/7.7/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.7&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.7/Microsoft.PowerShell.Core/About/about_Arrays.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Arrays.md new file mode 100644 index 00000000000..a5db8306aad --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Arrays.md @@ -0,0 +1,1195 @@ +--- +description: Describes arrays, which are data structures designed to store collections of items. +Locale: en-US +ms.date: 03/24/2026 +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.7&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 subexpression 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) +``` + +PowerShell 7.6-preview.5 added `PSForEach()` as an alias for the `ForEach()` +method and `PSWhere()` as an alias for the `Where()` method. Use these aliases +to avoid conflicts with `ForEach()` and `Where()` that might be defined on the +base class of the object. For example, the `System.Collections.Generic.List` +class defines its own `ForEach()` method. Use `PSForEach()` to avoid calling +the base class method. + +#### ForEach(scriptblock expression) + +#### ForEach(scriptblock expression, object[] arguments) + +This method was added in PowerShell v4. + +> [!NOTE] +> The syntax requires the usage of a scriptblock. 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 scriptblock +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 +``` + +> [!NOTE] +> The `ForEach()` method wraps properties into a collection before enumeration. +> Using `ForEach()` normally returns all items in both array. However, if you +> want to access elements of the wrapped collection, you need to use two +> indices. + +Consider the following example where the object `$myObject` has a property with +single value and a property containing an array of 11 integers. + +```powershell +$myObject = [pscustomobject]@{ + singleValue = 'Hello' + arrayValue = @(0..10) +} +``` + +When you use the `ForEach()` method to access a property of the object, the +property is wrapped in a collection. + +```powershell +PS> $myObject.ForEach('singleValue').GetType().Name +Collection`1 +PS> $myObject.ForEach('singleValue')[0].GetType().Name +String +PS> $myObject.ForEach('singleValue') # Enumerate the collection object +Hello +``` + +To access the an element of the array, you need to use two indices. + +```powershell +PS> $myObject.ForEach('arrayValue').GetType().Name +Collection`1 +# A single Collection item +PS> $myObject.ForEach('arrayValue').Count +1 +# First item in the collection is an array of 11 items +PS> $myObject.ForEach('Value')[0].Count +11 +# Access the first item in the array of 11 items +PS> $myObject.ForEach('Value')[0][0] +0 +``` + +This is different than using the `ForEach()` method using with a scriptblock to +access the **Value** property of each object. + +```powershell +PS> $myObject.ForEach({$_.Value}).Count # An array of 11 items +11 +``` + +Use the scriptblock syntax to avoid the wrapping behavior when you want to +access complex property types, such as arrays or nested objects. + +#### ForEach(string methodName) + +#### ForEach(string methodName, object[] arguments) + +You can use the `ForEach()` method to execute an object's 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 scriptblock 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 scriptblock. 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 +``` + +PowerShell 7.6-preview.5 added `PSForEach()` as an alias for the `ForEach()` +method and `PSWhere()` as an alias for the `Where()` method. Use these aliases +to avoid conflicts with `ForEach()` and `Where()` that might be defined on the +base class of the object. For example, the `System.Collections.Generic.List` +class defines its own `ForEach()` method. Use `PSForEach()` to avoid calling +the base class method. + +#### 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 scriptblock 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 scriptblock 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.7/Microsoft.PowerShell.Core/About/about_Assignment_Operators.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Assignment_Operators.md new file mode 100644 index 00000000000..e609acfa3a9 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Assignment_Operators.md @@ -0,0 +1,892 @@ +--- +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.7&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 +``` + +```Output +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.7/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md new file mode 100644 index 00000000000..aa1f1bc8de7 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Automatic_Variables.md @@ -0,0 +1,1163 @@ +--- +description: Describes variables that store state information for PowerShell. These variables are created and maintained by PowerShell. +Locale: en-US +ms.date: 04/02/2026 +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.7&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. + +## Long description + +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] + +### `$$` + +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 scriptblock. 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 a non-terminating 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` scriptblock. + +### `$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, scriptblocks (which +are unnamed functions), and script files (which are saved scriptblocks). + +- 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 scriptblock. + +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 scriptblocks. 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. + +> [!IMPORTANT] +> Since this property contains data explicitly provided by the client, using +> this for security decisions could allow attackers to bypass authorization +> controls. Never use this data for trust decisions. +> [Validate all user input][78] when used for other application logic. + +### `$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 scriptblocks 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 scriptblocks. In a scriptblock 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 scriptblocks +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 +[78]: https://top10proactive.owasp.org/archive/2024/the-top-10/c3-validate-input-and-handle-exceptions/ diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Booleans.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Booleans.md new file mode 100644 index 00000000000..f39e5797241 --- /dev/null +++ b/reference/7.7/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.7&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.7/Microsoft.PowerShell.Core/About/about_Break.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Break.md new file mode 100644 index 00000000000..218f4859cd1 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Break.md @@ -0,0 +1,236 @@ +--- +description: Describes a statement you can use to immediately exit `foreach`, `for`, `while`, `do`, `switch`, or `trap` statements. +Locale: en-US +ms.date: 01/18/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_break?view=powershell-7.7&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 () { + foreach ($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` +scriptblock, 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.7/Microsoft.PowerShell.Core/About/about_Built-in_Functions.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Built-in_Functions.md new file mode 100644 index 00000000000..26f1938bd29 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Built-in_Functions.md @@ -0,0 +1,105 @@ +--- +description: Describes the built-in functions in PowerShell. +Locale: en-US +ms.date: 03/01/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_built-in_functions?view=powershell-7.7&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` (alias: `man`) + +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` (alias: `md`) + +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. + +## `exec` + +Some native Unix commands shell out to run something (like ssh) and use the +built-in bash command `exec` to spawn a new process that replaces the current +one. PowerShell 7.3.1 adds the `exec` function to wrap the +[Switch-Process](xref:Microsoft.PowerShell.Core.Switch-Process) cmdlet. +`Switch-Process` calls the native Unix `execv()` function to provide similar +behavior as POSIX shells. + +## 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.7/Microsoft.PowerShell.Core/About/about_Calculated_Properties.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Calculated_Properties.md new file mode 100644 index 00000000000..aec893e8f91 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Calculated_Properties.md @@ -0,0 +1,536 @@ +--- +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: 01/18/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_calculated_properties?view=powershell-7.7&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 you to create new properties on +those output objects. You can use these parameters to generate new, calculated +properties on output objects based on the values of input objects. The input +object can be accessed using the `$_` or `$PSItem` automatic variable within +the `Expression` member a calculated property. + +The calculated property is defined as a [hashtable][03] containing key-value +pairs that specify the value of the newly calculated property. Some commands +support other key-value pairs that control how the property is displayed in the +output. + +## 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 scriptblock 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 scriptblock 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 scriptblock 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 scriptblock 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 scriptblock. + +### 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 scriptblock _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 scriptblock is converted + to a string and used as the name of the property in the output. + +- `Expression` scriptblocks run in _child_ scopes, meaning that the caller's + variables can't be directly modified. + +- Pipeline logic is applied to the output from `Expression` scriptblocks. This + means that outputting a single-element array causes that array to be + unwrapped. + +- For most cmdlets, errors inside expression scriptblocks 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.7/Microsoft.PowerShell.Core/About/about_Calling_Generic_Methods.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Calling_Generic_Methods.md new file mode 100644 index 00000000000..679758f90fd --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Calling_Generic_Methods.md @@ -0,0 +1,104 @@ +--- +description: Describes how to call generic methods of .NET types in PowerShell +Locale: en-US +ms.date: 02/02/2022 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_calling_generic_methods?view=powershell-7.7&WT.mc_id=ps-gethelp +schema: 2.0.0 +title: about_Calling_Generic_Methods +--- +# about_Calling_Generic_Methods + +## Short description + +A generic type is a parameterized type definition that you instantiate with +concrete type arguments (like `List`), giving reusable, type-safe code that +the compiler and CLR handle efficiently. + +## Long description + +Generics let you tailor a method, class, structure, or interface to the precise +data type it acts upon. For example, instead of using the +[System.Collections.Hashtable][01] class, which allows keys and values to be +of any type, you can use the [System.Collections.Generic.Dictionary][02] +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[T]()`. The .NET **Array** class has a static, +generic method `Empty[T]()` 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][03]. + +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][04]. + +## 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[T]` object that can only contain +integers. `List[T]` is a generic class that allows you to specify the type of +its members when you create it. +`[System.Linq.Enumerable]::Select[T1,T2](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 +``` + + +[01]: xref:System.Collections.Hashtable +[02]: xref:System.Collections.Generic.Dictionary%602 +[03]: https://www.leeholmes.com/invoking-generic-methods-on-non-generic-classes-in-powershell/ +[04]: /dotnet/standard/generics/ diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md new file mode 100644 index 00000000000..ca328260f44 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md @@ -0,0 +1,258 @@ +--- +description: This article explains how PowerShell handles case-sensitivity. +Locale: en-US +ms.date: 01/06/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-7.7&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 case-insensitive wherever possible while +preserving case and not breaking the underlying OS. + +Windows-based systems are case-insensitive for most operations. However, +non-Windows systems are case-sensitive for most operations, especially for +file system and environment variable access. + +PowerShell is guaranteed to be case-insensitive on all systems for the +following areas: + +- Variable names +- Operator names +- Non-dictionary member-access +- Command discovery of PowerShell commands and aliases. This excludes + ExternalScript and Application commands. +- Parameter names and aliases +- PowerShell language keywords +- `using namespace` statements +- Type literals +- `#Requires` statements +- Comment-based help keywords +- PSProvider names +- PSDrive names +- Scope modifiers + +## Special cases + +- 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 file system. 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. + +- [PS providers][05]: + + The `FileSystem` and `Environment` providers are case-sensitive on + non-Windows systems. Generally, operations involving paths or environment + variables are case-sensitive on such systems. + + However, [wildcard matching][09] by [provider cmdlets][02] is + case-insensitive, irrespective of the system. + + ```powershell + PS /home/user01> New-Item -Path Temp:foo.txt -Force + + Directory: /tmp + + UnixMode User Group LastWriteTime Size Name + -------- ---- ----- ------------- ---- ---- + -rw-r--r-- user01 user01 1/6/2026 10:53 0 foo.txt + + PS /home/user01> (Get-Item -Path Temp:FOO.txt).Name + Get-Item: Cannot find path 'Temp:/FOO.txt' because it does not exist. + + PS /home/user01> (Get-Item -Path Temp:F[O]*.txt).Name + foo.txt + + PS /home/user01> (Get-Item -Path Env:hOM[E]).Name + HOME + ``` + +- Parameter set names are case-sensitive. + + The `DefaultParameterSetName` case must be identical to `ParameterSetName`. + +- .NET methods often exhibit case-sensitive behavior by default. + + Examples include: + + - Equivalent .NET methods (without explicit opt-in) for common PowerShell + operators such as: + - `Array.Contains()`, `String.Contains()`, `String.Replace()`, + `Regex.Match()`, `Regex.Replace()` + - Reflection; member names must use the correct case. + - Non-literal dictionary instantiation. For example: + - `[hashtable]::new()` has case-sensitive keys, whereas a hashtable + literal `@{}` has case-insensitive keys. + - `[ordered]::new()` has case-sensitive keys, whereas a `[ordered] @{}` has + case-insensitive keys. The `[ordered]` type _accelerator_ isn't available + in PowerShell v5.1 and earlier. + - Explicitly calling `Enum.Parse()` is case-sensitive by default, whereas + PowerShell typically handles enums in a case-insensitive manner. + +- `-Unique` cmdlets: + - [`Select-Object -Unique`][21] and [`Get-Unique`][15] are case-sensitive by + default. The [`-CaseInsensitive`][20] switch was added in PS v7.4. + - [`Sort-Object -Unique`][25] is case-insensitive by default, but has always + had the [`-CaseSensitive`][24] switch. + +- [`Compare-Object`][11] is case-insensitive by default, but has a + [`-CaseSensitive`][12] switch. Comparison of `[char]` types is case-sensitive + by default. String comparison is case-insensitive by default. + + ```powershell + # Compare strings - Equal (no output) + Compare-object -ReferenceObject a -DifferenceObject A + # Compare chars - Different (output) + Compare-object -ReferenceObject ([char] 'a') -DifferenceObject ([char] 'A') + ``` + +- [`ConvertFrom-Json -AsHashtable`][13]: + - `-AsHashtable` was added in PS v6. In PS v7.3, a change was made to treat + JSON keys as case-sensitive when this parameter is specified. + - With the parameter, an object of type + [`Management.Automation.OrderedHashtable`][27] is emitted, which has + case-sensitive keys. + - Without the parameter, JSON keys are treated as case-insensitive. Output + is a custom object; last case-insensitive key wins. + - https://github.com/PowerShell/PowerShell/issues/19928 + +- [`Group-Object`][16]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][18] + switch. + - In Windows PowerShell v5.1, `-CaseSensitive` and [`-AsHashtable`][17] + produces a case-insensitive hashtable. Duplicate keys result in an error. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + Group-Object : The objects grouped by this property cannot be expanded + because there is a key duplication. Provide a valid value for the + property, and then try again. + At line:2 char:11 + + Group-Object -Property Foo -CaseSensitive -AsHashtable + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo : InvalidArgument: (:) [Group-Object], Exception + + FullyQualifiedErrorId : The objects grouped by this property + cannot be expanded because there is a key duplication. Provide a valid + value for the property, and then try again.,Microsoft.PowerShell.Comman + ds.GroupObjectCommand + ``` + + - In PowerShell v7 and higher, `-CaseSensitive` and `-AsHashtable` produces a + case-sensitive hashtable. No error occurs with duplicate keys. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + Name Value + ---- ----- + Bar {@{Foo=Bar}} + bar {@{Foo=bar}} + ``` + +- [`Select-String`][22]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][23] switch. + +- [`Get-Command`][14] and command discovery/invocation: + - On case-sensitive file systems, discovery and invocation of + `ExternalScript` and `Application` command are case-sensitive. + - `Get-Command` wildcard matching with these types is also case-sensitive. + - All other [`CommandTypes`][26] are case-insensitive. + +- [Comparison operators][03]: + - By default, operators are case-insensitive. + - `-c*` operators are case-sensitive. + - `-i*` operators are case-insensitive. + - `-replace`/`-ireplace` is case-insensitive by default, _except_ with [named + capture groups][01], which are case-sensitive. + + ```powershell + 'Bar' -replace '(?a)', '${a}${a}' + # Baar + + 'Bar' -replace '(?a)', '${A}${A}' + # B${A}${A}r + ``` + +- [`-split` operator][10]: + - `-split` and `-isplit` are case-insensitive. + - `-csplit` is case-sensitive, _unless_ the `IgnoreCase` option is specified. + + ```powershell + 'Bar' -csplit 'A', 0 + # Bar + + 'Bar' -csplit 'A', 0, 'IgnoreCase' + # B + # r + ``` + +- [Tab completion][07]: + - On case-sensitive file systems, tab completion and globbing are both + case-insensitive. For example, `TabExpansion2 -inputScript ./foo` will + complete to `./Foo.txt` on Linux. + +- [`using`][08] statement: + - On case-sensitive file systems, `using module` and `using assembly` are + case-sensitive when a path is specified. + - `using module` with just a module name is case-insensitive. + - `using namespace` is always case-insensitive. + +- [Special characters][06]: + - Escape sequences like `` `n `` are case-sensitive. + +## See also + +- [about_Environment_Variables][04] +- [Import-Module][19] + + +[01]: /dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-named-group +[02]: /powershell/scripting/developer/provider/provider-cmdlets +[03]: about_comparison_operators.md +[04]: about_Environment_Variables.md +[05]: about_providers.md +[06]: about_special_characters.md +[07]: about_tab_expansion.md +[08]: about_using.md +[09]: about_wildcards.md +[10]: about_split.md +[11]: xref:Microsoft.PowerShell.Utility.Compare-Object +[12]: xref:Microsoft.PowerShell.Utility.Compare-Object#-casesensitive +[13]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Json#-ashashtable +[14]: xref:Microsoft.PowerShell.Core.Get-Command +[15]: xref:Microsoft.PowerShell.Utility.Get-Unique +[16]: xref:Microsoft.PowerShell.Utility.Group-Object +[17]: xref:Microsoft.PowerShell.Utility.Group-Object#-ashashtable +[18]: xref:Microsoft.PowerShell.Utility.Group-Object#-casesensitive +[19]: xref:Microsoft.PowerShell.Core.Import-Module +[20]: xref:Microsoft.PowerShell.Utility.Select-Object#-caseinsensitive +[21]: xref:Microsoft.PowerShell.Utility.Select-Object#-unique +[22]: xref:Microsoft.PowerShell.Utility.Select-String +[23]: xref:Microsoft.PowerShell.Utility.Select-String#-casesensitive +[24]: xref:Microsoft.PowerShell.Utility.Sort-Object#-casesensitive +[25]: xref:Microsoft.PowerShell.Utility.Sort-Object#-unique +[26]: xref:System.Management.Automation.CommandTypes +[27]: xref:System.Management.Automation.OrderedHashtable diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Character_Encoding.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Character_Encoding.md new file mode 100644 index 00000000000..c6dc1751d78 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Character_Encoding.md @@ -0,0 +1,243 @@ +--- +description: Describes how PowerShell uses character encoding for input and output of string data. +Locale: en-US +ms.date: 04/08/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.7&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][08]. + +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][03] 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][07] 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][01]. + +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 three default variables that control the default encoding +behavior. + +- `$PSDefaultParameterValues` +- `$OutputEncoding` +- `$PSApplicationOutputEncoding` + +For more information, see [about_Preference_Variables][05]. + +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 don't +> 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 +when sending data to external programs. The `$PSApplicationOutputEncoding` +variable affects the encoding PowerShell uses to read data from external +programs. They have no effect on the encoding that the output redirection +operators and PowerShell cmdlets use to save to files. + +## See also + +- [about_Preference_Variables][05] +- [Byte order mark][06] +- [Code Pages - Win32 apps][04] +- [Encoding.CodePage][01] +- [Introduction to character encoding in .NET][02] +- [The Unicode Standard][08] +- [UTF-16LE][07] + + +[01]: /dotnet/api/system.text.encoding.codepage +[02]: /dotnet/standard/base-types/character-encoding-introduction +[03]: /globalization/encoding/byte-order-mark +[04]: /windows/win32/intl/code-pages +[05]: about_Preference_Variables.md +[06]: https://wikipedia.org/wiki/Byte_order_mark +[07]: https://wikipedia.org/wiki/UTF-16 +[08]: https://www.unicode.org/standard/standard.html diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_CimSession.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_CimSession.md new file mode 100644 index 00000000000..acbecbdff39 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_CimSession.md @@ -0,0 +1,76 @@ +--- +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.7&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][01]. + +## 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][02]. + +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][01] +- [New-CimSession][03] + + +[01]: about_PSSessions.md +[02]: /previous-versions/windows/desktop/wmi_v2/cdxml-overview +[03]: xref:CimCmdlets.New-CimSession diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes.md new file mode 100644 index 00000000000..568483d10e5 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes.md @@ -0,0 +1,854 @@ +--- +description: Describes how you can use classes to create your own custom types. +Locale: en-US +ms.date: 01/22/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-7.7&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 `` 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 uses runtime type +> conversion to assign the values provided. + +## 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 - Using instantiation syntax + +This example defines a **Book** class with several properties, but no +constructor. + +```powershell +class Book { + # Class properties + [string] $Title + [string] $Author + [string] $Synopsis + [string] $Publisher + [datetime] $PublishDate + [int] $PageCount + [string[]] $Tags +} +``` + +The following example shows how the default constructor can assign the values +from a compatible value using type coercion. In this example, a hashtable is +used to provide the property values. + +```powershell +$Book1 = [Book] @{ + Title = '1984' + Author = 'George Orwell' + Synopsis = '' + Publisher = 'Secker & Warburg' + PublishDate = '1949-06-08' + PageCount = 328 + Tags = @('Dystopian', 'Political Fiction', 'Social Science Fiction') +} +$Book1 +``` + +```Output +Title : 1984 +Author : George Orwell +Synopsis : +Publisher : Secker & Warburg +PublishDate : 6/8/1949 12:00:00 AM +PageCount : 328 +Tags : {Dystopian, Political Fiction, Social Science Fiction} +``` + +The key-value pairs of the hashtable are assigned to the instance properties. +If any key in the hashtable isn't a valid property name, instantiation fails. + +In this example, an array is used to provide the values for the generic list. + +```powershell +$List = [System.Collections.Generic.List[int]] @(42, 43) +$List +``` + +```Output +42 +43 +``` + +### Example 3 - 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 4 - Class with static members + +The **BookList** class in this example builds on the **Book** class in the +previous example. 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 5 - 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][09]. + +## 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][06]. + +## 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][02]. + +## 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][13]. For more +information about hidden properties, see [about_Classes_Properties][10]. For +more information about hidden methods, see [about_Classes_Methods][07]. For +more information about hidden constructors, see +[about_Classes_Constructors][03]. + +## 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][11]. For more information about static methods, see +[about_Classes_Methods][08]. For more information about static constructors, +see [about_Classes_Constructors][04]. + +## 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][05]. + +## 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 5][01]. + +## Export 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 import 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][16]. + +## Load 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][17]. + +## 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][02] +- [about_Classes_Inheritance][05] +- [about_Classes_Methods][06] +- [about_Classes_Properties][09] +- [about_Enum][12] +- [about_Hidden][13] +- [about_Language_Keywords][14] +- [about_Methods][15] +- [about_Using][16] + + +[01]: #example-5---class-definition-with-and-without-runspace-affinity +[02]: about_Classes_Constructors.md +[03]: about_Classes_Constructors.md#hidden-constructors +[04]: about_Classes_Constructors.md#static-constructors +[05]: about_Classes_Inheritance.md +[06]: about_Classes_Methods.md +[07]: about_Classes_Methods.md#hidden-methods +[08]: about_Classes_Methods.md#static-methods +[09]: about_Classes_Properties.md +[10]: about_Classes_Properties.md#hidden-properties +[11]: about_Classes_Properties.md#static-properties +[12]: about_Enum.md +[13]: about_Hidden.md +[14]: about_language_keywords.md +[15]: about_methods.md +[16]: about_Using.md +[17]: xref:System.Management.Automation.PSReference diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Constructors.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Constructors.md new file mode 100644 index 00000000000..7836f8d7198 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Constructors.md @@ -0,0 +1,557 @@ +--- +description: Describes how to define constructors for PowerShell classes. +Locale: en-US +ms.date: 10/22/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_constructors?view=powershell-7.7&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. If the static constructor of the derived class doesn't depend on the base + class, the static constructor of the derived class is called first. +1. If the static constructor of the derived class depends on the base class, + the static constructor of the base class is called before executing the line + of code in the derived class that depends on base. +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#define-instance-methods-with-update-typedata +[08]: about_Classes_Properties.md#define-instance-properties-with-update-typedata +[09]: about_Classes_Properties.md +[10]: about_Classes.md +[11]: about_Classes_Inheritance.md diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Inheritance.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Inheritance.md new file mode 100644 index 00000000000..1047805882d --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Inheritance.md @@ -0,0 +1,1612 @@ +--- +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.7&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 type as long as the +type parameter is already defined at parse time. + +#### 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#export-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.7/Microsoft.PowerShell.Core/About/about_Classes_Methods.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Methods.md new file mode 100644 index 00000000000..8db33c7360a --- /dev/null +++ b/reference/7.7/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.7&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 `$Strict` 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 +``` + +## Define 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]: #define-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.7/Microsoft.PowerShell.Core/About/about_Classes_Properties.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Properties.md new file mode 100644 index 00000000000..21ab7843371 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Classes_Properties.md @@ -0,0 +1,960 @@ +--- +description: Describes how to define properties for PowerShell classes. +Locale: en-US +ms.date: 01/21/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_properties?view=powershell-7.7&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 be overridden to any valid value, as defined by the static property's +> type and attributes. + +## 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]. + +## Use 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]. + +## Define 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.7/Microsoft.PowerShell.Core/About/about_Command_Precedence.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Command_Precedence.md new file mode 100644 index 00000000000..54cdcbc8d7d --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Command_Precedence.md @@ -0,0 +1,344 @@ +--- +description: Describes how PowerShell determines which command to run. +Locale: en-US +ms.date: 01/18/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_command_precedence?view=powershell-7.7&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. + +## Resolve 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. + +## Find 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 scriptblocks 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. + +## Avoid 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 +``` + +## Run 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.7/Microsoft.PowerShell.Core/About/about_Command_Syntax.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Command_Syntax.md new file mode 100644 index 00000000000..68bc73b88f0 --- /dev/null +++ b/reference/7.7/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.7&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.7/Microsoft.PowerShell.Core/About/about_Comment_Based_Help.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Comment_Based_Help.md new file mode 100644 index 00000000000..18270ebd367 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Comment_Based_Help.md @@ -0,0 +1,857 @@ +--- +description: Describes how to write comment-based help content for functions and scripts. +Locale: en-US +ms.date: 05/21/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.7&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 this article in the 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. Repeat this keyword for each +input type. + +### `.OUTPUTS` + +The .NET type of the objects that the cmdlet returns. You can also include a +description of the returned objects. Repeat this keyword for each output type. + +### `.NOTES` + +Additional information about the function or script. + +### `.LINK` + +The name of a related topic. Repeat this 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 +filename 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. +Beginning in PowerShell 5.0, functions that are exported by a module can be +documented in a help file that's named for the module. You don't need to use +`.EXTERNALHELP` comment keyword. For example, if the `Test-Function` function +is exported by the `MyModule` module, you can name the help file +`MyModule-help.xml`. The `Get-Help` cmdlet looks for help for the +`Test-Function` function in the `MyModule-help.xml` file in the module +directory. + +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> Add-Extension -Name "File" +File.txt + +.EXAMPLE + +PS> Add-Extension -Name "File" -Extension "doc" +File.doc + +.EXAMPLE + +PS> Add-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> Add-Extension -Name "File" +File.txt + +Example 2 + +PS> Add-Extension -Name "File" -Extension "doc" +File.doc + +Example 3 + +PS> Add-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> Add-Extension -Name "File" +File.txt + +.EXAMPLE + +PS> Add-Extension -Name "File" -Extension "doc" +File.doc + +.EXAMPLE + +PS> Add-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.7/Microsoft.PowerShell.Core/About/about_Comments.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Comments.md new file mode 100644 index 00000000000..ffdf8264f3e --- /dev/null +++ b/reference/7.7/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.7&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 dependent 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.7/Microsoft.PowerShell.Core/About/about_CommonParameters.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_CommonParameters.md new file mode 100644 index 00000000000..e26c5c2c303 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_CommonParameters.md @@ -0,0 +1,843 @@ +--- +description: Describes the parameters that can be used with any cmdlet. +Locale: en-US +ms.date: 04/02/2026 +no-loc: [Confirm, Debug, ErrorAction, ErrorVariable, InformationAction, InformationVariable, OutBuffer, OutVariable, PipelineVariable, ProgressAction, Verbose, WarningAction, WarningVariable, WhatIf] +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.7&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 parameters + +### -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 overrides the value of the `$ErrorActionPreference` variable for +non-terminating errors generated by the command or 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 doesn't prevent statement-terminating errors +(such as missing data, parameters that aren't valid, or insufficient +permissions) from stopping the current statement. However, when set to `Stop`, +it escalates non-terminating errors to script-terminating errors, making them +catchable by `try/catch`. For more information about error categories, see +[about_Error_Handling][15]. + +- `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 non-terminating error 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. The + `Stop` value escalates the non-terminating error to a terminating error + by generating an `ActionPreferenceStopException`. The error can then + be caught by a `try/catch` block or `trap` statement. +- `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 scriptblocks: `begin`, `process`, +> and `end`. When using the `PipelineVariable` parameter with advanced +> functions, only values from the first defined scriptblock 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 example illustrates how the `PipelineVariable` works. In this +example, five numbers are piped into the first `ForEach-Object` command. Each +item in the pipeline is stored in the pipeline variable named `$Temp`. + +The `Process` block of the first `ForEach-Object` command pipes the pipeline +item into the downstream `ForEach-Object` command. The state of the variables +is displayed in each step. + +```powershell +# Create a variable named $Temp +$Temp = 8 +Get-Variable Temp | Format-Table + +$InformationPreference = 'Continue' +Write-Information '-------------------------------------------------' +111,222,333,444,555 | ForEach-Object -PipelineVariable Temp -Begin { + + # Note that the newly create $Temp variable doesn't contain the value 8 + # assigned before the pipeline started and that $PSItem is empty in + # the Begin block. + Write-Information "Upstream (Begin): PSItem = '$PSItem', Temp = '$Temp'" + +} -Process { + + Write-Information "Upstream (Process): PSItem = '$PSItem', Temp = '$Temp'" + return $PSItem + +} | ForEach-Object -Process { + + Write-Information "`tDownstream: PSItem = '$PSItem', Temp = '$Temp'" + +} +Write-Information '-------------------------------------------------' + +# The $Temp variable is deleted when the pipeline finishes +Get-Variable Temp | Format-Table +``` + +```Output +Name Value +---- ----- +Temp 8 + +------------------------------------------------- +Upstream (Begin): PSItem = '', Temp = '' +Upstream (Process): PSItem = '111', Temp = '' + Downstream: PSItem = '111', Temp = '111' +Upstream (Process): PSItem = '222', Temp = '111' + Downstream: PSItem = '222', Temp = '222' +Upstream (Process): PSItem = '333', Temp = '222' + Downstream: PSItem = '333', Temp = '333' +Upstream (Process): PSItem = '444', Temp = '333' + Downstream: PSItem = '444', Temp = '444' +Upstream (Process): PSItem = '555', Temp = '444' + Downstream: PSItem = '555', Temp = '555' +------------------------------------------------- + +Name Value +---- ----- +Temp +``` + +> [!CAUTION] +> There are two known issues with using the **PipelineVariable** parameter in a +> pipeline that includes CimCmdlets or CDXML cmdlets. In the following +> examples, `Get-Partition` is a CDXML function and `Get-CimInstance` is a +> CimCmdlet. + +**Issue 1**: CDXML functions use `[CmdletBinding()]`, which allows the +**PipelineVariable** parameter. + +```powershell +Get-Partition -pv pvar +``` + +However, when you use **PipelineVariable** in Windows PowerShell v5.1, you +receive the following error. + +```Output +Get-Partition : Cannot retrieve the dynamic parameters for the cmdlet. +Object reference not set to an instance of an object. + +At line:1 char:1 ++ get-partition -PipelineVariable pvar ++ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo : InvalidArgument: (:) [Get-Partition], ParameterBindingException + + FullyQualifiedErrorId : GetDynamicParametersException,Get-Partition +``` + +**Issue 2**: When the preceding command is _not_ a CDXML command and the +downstream contains either command type, the **PipelineVariable** remains as +the last accumulated object. + +```powershell +Get-CimInstance Win32_DiskDrive -pv pvar | + ForEach-Object { + Write-Host "Upstream: Disk $($pvar.Index)" + return [pscustomobject]@{ DiskNumber = $_.Index } + } | Get-Partition | ForEach-Object { + Write-Host "Downstream: Disk $($pvar.Index)" + } +``` + +Notice that the value of `$pvar` set to the last object in the pipeline for +the second `ForEach-Object` command. + +```Output +Upstream: Disk 1 +Upstream: Disk 2 +Upstream: Disk 0 +Downstream: Disk 0 +Downstream: Disk 0 +Downstream: Disk 0 +Downstream: Disk 0 +Downstream: Disk 0 +Downstream: Disk 0 +``` + +### -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 parameters + +### -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] +- [about_Error_Handling][15] +- [`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 +[15]: about_Error_Handling.md + diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Comparison_Operators.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Comparison_Operators.md new file mode 100644 index 00000000000..8c9ffb7b35c --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Comparison_Operators.md @@ -0,0 +1,833 @@ +--- +description: Describes the operators that compare values in PowerShell. +Locale: en-US +ms.date: 01/18/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.7&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` - finds and replaces strings matching a + regex pattern + +**Containment** + +- `-contains`, `-icontains`, `-ccontains` - collection contains a value +- `-notcontains`, `-inotcontains`, `-cnotcontains` - collection doesn't + contain a value +- `-in`, `-iin`, `-cin` - value is in a collection +- `-notin`, `-inotin`, `-cnotin` - 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 +``` + +For best results, the right-hand side of the `-like` and `-notlike` operators +should be a string literal containing the wildcard expression. PowerShell +passes the wildcard expression to the wildcard expression parser. To match one +of the wildcard characters (`*`, `?`, or `[ ]`), you must escape it with a +backtick (`` ` ``) character. For example, to match a literal `?`, use +`` `? `` in the wildcard expression. If you use an expandable string +expression PowerShell expands the string before passing it to the wildcard +parser, which results in unescaped characters being sent as wildcards. + +```powershell +# Escaped literals in an expandable string +PS> "f`?`?" +f?? +# Escaped literals in a literal string +PS> 'f`?`?' +f`?`? +# Comparison containing 2 wildcards +PS> 'f??' -like 'f??' +True +PS> 'for' -like 'f??' +True +# Comparison containing literal '?' characters +PS> 'f??' -like 'f`?`?' +True +PS> 'for' -like 'f`?`?' +False +``` + +### -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 scriptblock + +In PowerShell 6 and later, the `-replace` operator also accepts a scriptblock +that performs the replacement. The scriptblock runs once for every match. + +Syntax: + +```powershell + -replace , {} +``` + +Within the scriptblock, 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 scriptblock 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.7/Microsoft.PowerShell.Core/About/about_Continue.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Continue.md new file mode 100644 index 00000000000..24ed97a3178 --- /dev/null +++ b/reference/7.7/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: 01/18/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_continue?view=powershell-7.7&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` scriptblock, +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.7/Microsoft.PowerShell.Core/About/about_Core_Commands.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Core_Commands.md new file mode 100644 index 00000000000..c2dd6240101 --- /dev/null +++ b/reference/7.7/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.7&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.7/Microsoft.PowerShell.Core/About/about_Data_Files.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Data_Files.md new file mode 100644 index 00000000000..dfbf4d59e9a --- /dev/null +++ b/reference/7.7/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.7&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.7/Microsoft.PowerShell.Core/About/about_Data_Sections.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Data_Sections.md new file mode 100644 index 00000000000..8ef9b1a9382 --- /dev/null +++ b/reference/7.7/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: 10/09/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_data_sections?view=powershell-7.7&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" } + @' +

Hello, World

+ '@ + ``` + +- Cmdlets that are permitted in a `data` section by default. 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.7/Microsoft.PowerShell.Core/About/about_Debuggers.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Debuggers.md new file mode 100644 index 00000000000..d5ecdcf0fd7 --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Debuggers.md @@ -0,0 +1,710 @@ +--- +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.7&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. 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.7/Microsoft.PowerShell.Core/About/about_Do.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Do.md new file mode 100644 index 00000000000..640b07e0ebb --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Do.md @@ -0,0 +1,107 @@ +--- +description: Runs a statement list one or more times, subject to a `while` or `until` condition. +Locale: en-US +ms.date: 01/18/2026 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_do?view=powershell-7.7&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 commands in a statement block, subject to a condition. Unlike the related +`while` loop, the statement 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 statement block has run. As in a `while` loop, +the statement 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 statement 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][02]. + +### 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][02] +- [about_Break][03] +- [about_Continue][05] +- [about_Operators][06] +- [about_Assignment_Operators][01] +- [about_Comparison_Operators][04] +- [about_While][07] + + +[01]: about_Assignment_Operators.md +[02]: about_Booleans.md +[03]: about_Break.md +[04]: about_Comparison_Operators.md +[05]: about_Continue.md +[06]: about_Operators.md +[07]: about_While.md + + + diff --git a/reference/7.7/Microsoft.PowerShell.Core/About/about_Enum.md b/reference/7.7/Microsoft.PowerShell.Core/About/about_Enum.md new file mode 100644 index 00000000000..eeccaefebdb --- /dev/null +++ b/reference/7.7/Microsoft.PowerShell.Core/About/about_Enum.md @@ -0,0 +1,1246 @@ +--- +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: 08/20/2025 +online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_enum?view=powershell-7.7&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. + +## SYNTAX + +In the definition, you can give labels any integer value. Labels with no value +assigned take the next integer value. + +Enum labels can only contain letters, underscores and digits, but must not +start with a digit. The label can't be a quoted string; it must parse as a +bareword string. Labels are parsed as strings not keywords. Therefore, it's +possible to create a label that's the same name as a language keyword (such as +`return`). + +Enumerations use the following syntaxes: + +- Integer enumeration definition syntax + + ```Syntax + [[]...] enum { +