diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md index 207072334c26..b11ed8d1bdce 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md @@ -1,7 +1,7 @@ --- description: Describes how to define and use parameter sets in advanced functions. Locale: en-US -ms.date: 03/27/2024 +ms.date: 03/26/2025 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parameter_sets?view=powershell-5.1&WT.mc_id=ps-gethelp title: about_Parameter_Sets --- @@ -64,12 +64,23 @@ one unique parameter. Parameters that don't have an assigned parameter set name belong to all parameter sets. +## Reserved parameter set name + +PowerShell reserves the parameter set name `__AllParameterSets` for special +handling. + +- This name is the default name of the parameter set that when you don't + explicitly define a parameter set name. +- When you have muliple parameter sets, you can use this name to define a + parameter that belongs to all parameter sets. +- Setting **DefaultParameterSetName** to `__AllParameterSets` in the + `[CmdletBinding()]` attribute has no effect. + ## Examples The following example function counts the number lines, characters, and words -in a text file. Using parameters, you can specify which values you want -returned and which files you want to measure. There are four parameter sets -defined: +in a text file. Using parameters, you can specify the values you want returned +and the files you want to measure. There are four parameter sets defined: - Path - PathAll diff --git a/reference/5.1/Microsoft.PowerShell.Management/Test-ComputerSecureChannel.md b/reference/5.1/Microsoft.PowerShell.Management/Test-ComputerSecureChannel.md index 21d7ec1e481b..1c990b5a60c1 100644 --- a/reference/5.1/Microsoft.PowerShell.Management/Test-ComputerSecureChannel.md +++ b/reference/5.1/Microsoft.PowerShell.Management/Test-ComputerSecureChannel.md @@ -34,6 +34,11 @@ more detailed test results, use the **Verbose** parameter. This cmdlet works much like `NetDom.exe`. Both NetDom and `Test-ComputerSecureChannel` use the **NetLogon** service to perform the actions. +> [!NOTE] +> This cmdlet only works on Domain Member computers. When you run it on Domain Controllers, it +> returns false positive errors. To verify and reset the secure channels for Domain Controllers, +> use `netdom.exe` or `nltest.exe`. + ## EXAMPLES ### Example 1: Test a channel between the local computer and its domain @@ -74,7 +79,8 @@ VERBOSE: "The secure channel between 'SERVER01' and 'net.fabrikam.com' is alive ``` This command uses the **Verbose** common parameter to request detailed messages about the operation. -For more information about **Verbose**, see [about_CommonParameters](../Microsoft.PowerShell.Core/About/about_CommonParameters.md). +For more information about **Verbose**, see +[about_CommonParameters](../Microsoft.PowerShell.Core/About/about_CommonParameters.md). ### Example 5: Test a connection before you run a script @@ -170,7 +176,7 @@ Accept wildcard characters: False ### -WhatIf -Shows what would happen if the cmdlet runs. The cmdlet is not run. +Shows what would happen if the cmdlet runs. The cmdlet isn't run. ```yaml Type: System.Management.Automation.SwitchParameter @@ -188,7 +194,8 @@ Accept wildcard characters: False 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). +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -218,3 +225,7 @@ This cmdlet returns `$true` if the connection is working correctly and `$false` [Restart-Computer](Restart-Computer.md) [Stop-Computer](Stop-Computer.md) + +[Use Netdom.exe to reset machine account passwords of a Windows Server domain controller](/troubleshoot/windows-server/windows-security/use-netdom-reset-domain-controller-password) + +[Nltest.exe](/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc731935(v=ws.11)) diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md index 4300a63a85be..861f4859b251 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md @@ -1,7 +1,7 @@ --- description: Describes how to define and use parameter sets in advanced functions. Locale: en-US -ms.date: 03/27/2024 +ms.date: 03/26/2025 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parameter_sets?view=powershell-7.4&WT.mc_id=ps-gethelp title: about_Parameter_Sets --- @@ -64,12 +64,23 @@ one unique parameter. Parameters that don't have an assigned parameter set name belong to all parameter sets. +## Reserved parameter set name + +PowerShell reserves the parameter set name `__AllParameterSets` for special +handling. + +- This name is the default name of the parameter set that when you don't + explicitly define a parameter set name. +- When you have muliple parameter sets, you can use this name to define a + parameter that belongs to all parameter sets. +- Setting **DefaultParameterSetName** to `__AllParameterSets` in the + `[CmdletBinding()]` attribute has no effect. + ## Examples The following example function counts the number lines, characters, and words -in a text file. Using parameters, you can specify which values you want -returned and which files you want to measure. There are four parameter sets -defined: +in a text file. Using parameters, you can specify the values you want returned +and the files you want to measure. There are four parameter sets defined: - Path - PathAll diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md index f50a0626037d..cfbd15ffd8e6 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md @@ -1,7 +1,7 @@ --- description: Describes how to define and use parameter sets in advanced functions. Locale: en-US -ms.date: 03/27/2024 +ms.date: 03/26/2025 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parameter_sets?view=powershell-7.5&WT.mc_id=ps-gethelp title: about_Parameter_Sets --- @@ -64,12 +64,23 @@ one unique parameter. Parameters that don't have an assigned parameter set name belong to all parameter sets. +## Reserved parameter set name + +PowerShell reserves the parameter set name `__AllParameterSets` for special +handling. + +- This name is the default name of the parameter set that when you don't + explicitly define a parameter set name. +- When you have muliple parameter sets, you can use this name to define a + parameter that belongs to all parameter sets. +- Setting **DefaultParameterSetName** to `__AllParameterSets` in the + `[CmdletBinding()]` attribute has no effect. + ## Examples The following example function counts the number lines, characters, and words -in a text file. Using parameters, you can specify which values you want -returned and which files you want to measure. There are four parameter sets -defined: +in a text file. Using parameters, you can specify the values you want returned +and the files you want to measure. There are four parameter sets defined: - Path - PathAll diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md index 61c42e08ebdd..b6469444b627 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Parameter_Sets.md @@ -1,7 +1,7 @@ --- description: Describes how to define and use parameter sets in advanced functions. Locale: en-US -ms.date: 03/27/2024 +ms.date: 03/26/2025 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parameter_sets?view=powershell-7.6&WT.mc_id=ps-gethelp title: about_Parameter_Sets --- @@ -64,12 +64,23 @@ one unique parameter. Parameters that don't have an assigned parameter set name belong to all parameter sets. +## Reserved parameter set name + +PowerShell reserves the parameter set name `__AllParameterSets` for special +handling. + +- This name is the default name of the parameter set that when you don't + explicitly define a parameter set name. +- When you have muliple parameter sets, you can use this name to define a + parameter that belongs to all parameter sets. +- Setting **DefaultParameterSetName** to `__AllParameterSets` in the + `[CmdletBinding()]` attribute has no effect. + ## Examples The following example function counts the number lines, characters, and words -in a text file. Using parameters, you can specify which values you want -returned and which files you want to measure. There are four parameter sets -defined: +in a text file. Using parameters, you can specify the values you want returned +and the files you want to measure. There are four parameter sets defined: - Path - PathAll diff --git a/reference/docs-conceptual/install/PowerShell-in-Docker.md b/reference/docs-conceptual/install/PowerShell-in-Docker.md index c7afc169dc7d..848f60e9a17f 100644 --- a/reference/docs-conceptual/install/PowerShell-in-Docker.md +++ b/reference/docs-conceptual/install/PowerShell-in-Docker.md @@ -1,83 +1,72 @@ --- -description: How to use PowerShell that's preinstalled in a Docker image. -ms.date: 08/01/2024 +description: How to use PowerShell in a Docker image. +ms.date: 03/11/2025 ms.devlang: powershell ms.topic: conceptual -title: Using PowerShell in Docker +title: Use PowerShell in Docker --- -# Using PowerShell in Docker +# Use PowerShell in Docker -We publish Docker images with PowerShell preinstalled. This article shows you how to get -started using PowerShell in the Docker container. +The .NET team publishes Docker images with PowerShell preinstalled. This article shows you how to +get started using PowerShell in the Docker container. -## Finding available images +## Find available images -The released images require Docker 17.05 or newer. It's also expected that you are able to run -Docker without `sudo` or local administrative rights. Please follow Docker's official -[instructions][01] to install `docker` correctly. +These images require Docker 17.05 or newer. Also, you must be able to run Docker without `sudo` or +local administrative rights. For install instructions, see Docker's official [documentation][02]. -The release containers derive from the official distribution image, then install dependencies, and -finally install the PowerShell package. +The .NET team publishes several Docker images designed for different development scenarios. Only the +image for the .NET SDK contains PowerShell. For more information, see +[Official .NET Docker images][01]. -These containers live at [Microsoft Artifact Registry][05]. +## Use PowerShell in a container -For more information about these Docker images, visit the [PowerShell-Docker][02] repository on -GitHub. - -## Using PowerShell in a container - -The following steps show the Docker commands required to download the image containing the latest -available stable version of PowerShell and start an interactive PowerShell session. +The following command downloads the image containing the latest available stable versions of the +.NET SDK and PowerShell. ```console -docker run -it mcr.microsoft.com/powershell +docker pull mcr.microsoft.com/dotnet/sdk:9.0 ``` -Use the following command to download and run the image containing the latest available preview -version of PowerShell. - -```console -docker run -it mcr.microsoft.com/powershell:preview -``` -> [!IMPORTANT] -> The Docker images are built from official operating system (OS) images provide by the OS -> distributor. These images may not have the latest security updates. Microsoft recommends that you -> update the OS packages to the latest version to ensure the latest security updates are applied. - -### Remove the image when no longer needed - -The following command is used to delete the Docker image when you no longer need it. +Use the following command to start an interactive PowerShell session in the container. ```console -docker rmi mcr.microsoft.com/powershell +docker run -it mcr.microsoft.com/dotnet/sdk:9.0 pwsh ``` -## Legal and Licensing +To download and run the latest Long Term Support (LTS) version of PowerShell, change the image name +to `mcr.microsoft.com/dotnet/sdk:8.0`. When you use these image tags, Docker downloads the +appropriate image for your host operating system. If you want an image for a specific operating +system, you can specify the operating system in the image tag. See the +[Microsoft Artifact Registry][07] for a list of available tags. -PowerShell is licensed under the [MIT license][03]. +- For more information about tags, the [Supported tag policy][06] +- For more information about supported operating systems, see the [Supported platforms policy][05] -### Windows Docker file and image licenses +## Support lifecycle -By requesting and using the Container OS Image for Windows containers, you acknowledge, understand, -and consent to the Supplemental License Terms available on Docker hub: +The [.NET support policy][03] defines how these images are supported. These images are provided for +development and testing purposes only. If you need a production-ready image, you should build your +own images. For more information about these Docker images, visit the [dotnet-docker][04] repository +on GitHub. -- [Window Server Core][06] -- [Nano Server][04] +The images previously published by the PowerShell team will be marked as deprecated in the Microsoft +Container Registry (MCR). -### Telemetry +## Telemetry -By default, PowerShell collects limited telemetry without personally identifiable information to -help aid development of future versions of PowerShell. To opt-out of sending telemetry, create an -environment variable called `POWERSHELL_TELEMETRY_OPTOUT` set to a value of `1` before starting -PowerShell from the installed location. The telemetry we collect falls under the -[Microsoft Privacy Statement][07]. +By default, PowerShell collects limited telemetry without personal data to help aid development of +future versions of PowerShell. To opt-out of sending telemetry, create an environment variable +called `POWERSHELL_TELEMETRY_OPTOUT` set to a value of `1` before starting PowerShell from the +installed location. The telemetry we collect falls under the [Microsoft Privacy Statement][08]. -[01]: https://docs.docker.com/engine/installation/ -[02]: https://github.com/PowerShell/PowerShell-Docker -[03]: https://github.com/PowerShell/PowerShell/tree/master/LICENSE.txt -[04]: https://mcr.microsoft.com/product/windows/nanoserver -[05]: https://mcr.microsoft.com/product/powershell -[06]: https://mcr.microsoft.com/product/windows/servercore -[07]: https://privacy.microsoft.com/privacystatement/ +[01]: /dotnet/architecture/microservices/net-core-net-framework-containers/official-net-docker-images +[02]: https://docs.docker.com/engine/installation/ +[03]: https://github.com/dotnet/core/blob/main/support.md +[04]: https://github.com/dotnet/dotnet-docker +[05]: https://github.com/dotnet/dotnet-docker/blob/main/documentation/supported-platforms.md +[06]: https://github.com/dotnet/dotnet-docker/blob/main/documentation/supported-tags.md +[07]: https://mcr.microsoft.com/en-us/artifact/mar/dotnet/sdk/about +[08]: https://privacy.microsoft.com/privacystatement/ diff --git a/reference/docs-conceptual/learn/ps101/06-flow-control.md b/reference/docs-conceptual/learn/ps101/06-flow-control.md index 33aa072cc047..7bafe96cb8ac 100644 --- a/reference/docs-conceptual/learn/ps101/06-flow-control.md +++ b/reference/docs-conceptual/learn/ps101/06-flow-control.md @@ -313,7 +313,7 @@ In this chapter, you learned about the different types of loops that exist in Po ## References -- [ForEach-Object][ForEach-Object] +- [ForEach-Object][foreach-object] - [about_Foreach][about-foreach] - [about_For][about-for] - [about_Do][about-do] diff --git a/reference/docs-conceptual/learn/ps101/08-powershell-remoting.md b/reference/docs-conceptual/learn/ps101/08-powershell-remoting.md index ed981f6a3906..ddbd56faa391 100644 --- a/reference/docs-conceptual/learn/ps101/08-powershell-remoting.md +++ b/reference/docs-conceptual/learn/ps101/08-powershell-remoting.md @@ -1,69 +1,69 @@ --- description: There are many different ways to run commands against remote computers in PowerShell. ms.custom: Contributor-mikefrobbins -ms.date: 12/08/2022 +ms.date: 03/25/2025 ms.reviewer: mirobb title: PowerShell remoting --- + # Chapter 8 - PowerShell remoting -PowerShell has many different ways to run commands against remote computers. In the last chapter, -you saw how to remotely query WMI using the CIM cmdlets. PowerShell also includes several cmdlets -that have a built-in **ComputerName** parameter. +PowerShell offers several ways to run commands against remote computers. In the last chapter, you +explored how to remotely query WMI using the CIM cmdlets. PowerShell also includes several cmdlets +that feature a built-in **ComputerName** parameter. -As shown in the following example, `Get-Command` can be used with the **ParameterName** parameter to -determine what commands have a **ComputerName** parameter. +As shown in the following example, you can use `Get-Command` with the **ParameterName** parameter to +identify cmdlets that include a **ComputerName** parameter. ```powershell Get-Command -ParameterName ComputerName ``` ```Output -CommandType Name Version Source ------------ ---- ------- ------ -Cmdlet Add-Computer 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Clear-EventLog 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Connect-PSSession 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Enter-PSSession 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Get-EventLog 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Get-HotFix 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Get-Process 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Get-PSSession 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Get-Service 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Get-WmiObject 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Invoke-Command 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Invoke-WmiMethod 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Limit-EventLog 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet New-EventLog 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet New-PSSession 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Receive-Job 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Receive-PSSession 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Register-WmiEvent 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Remove-Computer 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Remove-EventLog 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Remove-PSSession 3.0.0.0 Microsoft.PowerShell.Core -Cmdlet Remove-WmiObject 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Rename-Computer 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Restart-Computer 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Send-MailMessage 3.1.0.0 Microsoft.PowerShell.Utility -Cmdlet Set-Service 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Set-WmiInstance 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Show-EventLog 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Stop-Computer 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Test-Connection 3.1.0.0 Microsoft.PowerShell.Management -Cmdlet Write-EventLog 3.1.0.0 Microsoft.PowerShell.Management +CommandType Name Version Source +----------- ---- ------- ------ +Cmdlet Add-Computer 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Clear-EventLog 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Connect-PSSession 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Enter-PSSession 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Get-EventLog 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Get-HotFix 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Get-Process 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Get-PSSession 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Get-Service 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Get-WmiObject 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Invoke-Command 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Invoke-WmiMethod 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Limit-EventLog 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet New-EventLog 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet New-PSSession 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Receive-Job 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Receive-PSSession 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Register-WmiEvent 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Remove-Computer 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Remove-EventLog 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Remove-PSSession 3.0.0.0 Microsoft.PowerShell.Core +Cmdlet Remove-WmiObject 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Rename-Computer 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Restart-Computer 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Send-MailMessage 3.1.0.0 Microsoft.PowerShell.Utility +Cmdlet Set-Service 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Set-WmiInstance 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Show-EventLog 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Stop-Computer 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Test-Connection 3.1.0.0 Microsoft.PowerShell.Management +Cmdlet Write-EventLog 3.1.0.0 Microsoft.PowerShell.Management ``` -Commands such as `Get-Process` and `Get-HotFix` have a **ComputerName** parameter. This isn't the -long-term direction that Microsoft is heading for running commands against remote computers. Even if -you find a command that has a **ComputerName** parameter, chances are that you'll need to specify -alternate credentials and it won't have a **Credential** parameter. And if you decided to run -PowerShell from an elevated account, a firewall between you and the remote computer can block the -request. +Commands such as `Get-Process` and `Get-HotFix` include a **ComputerName** parameter, but this +approach isn't the long-term direction Microsoft recommends for running commands against remote +systems. Even when you find a command with a **ComputerName** parameter, it often lacks a +**Credential** parameter, making it difficult to specify alternate credentials. Running PowerShell +from an elevated session doesn't guarantee success, as a network firewall can block the request +between your system and the remote computer. -To use the PowerShell remoting commands that are demonstrated in this chapter, PowerShell remoting -must be enabled on the remote computer. Use the `Enable-PSRemoting` cmdlet to enable PowerShell -remoting. +To use the PowerShell remoting commands demonstrated in this chapter, PowerShell remoting must be +enabled on the remote computer. You can enable it by running the `Enable-PSRemoting` cmdlet. ```powershell Enable-PSRemoting @@ -78,44 +78,41 @@ WinRM has been updated for remote management. WinRM firewall exception enabled. ``` -## One-To-One Remoting - -If you want your remote session to be interactive, then one-to-one remoting is what you want. -This type of remoting is provided via the `Enter-PSSession` cmdlet. +## One-to-one remoting -In the last chapter, I stored my domain admin credentials in a variable named `$Cred`. If you -haven't already done so, go ahead and store your domain admin credentials in the `$Cred` variable. +If you want an interactive remote session, one-to-one remoting is what you want. This type of +remoting is provided via the `Enter-PSSession` cmdlet. -This allows you to enter the credentials once and use them on a per command basis as long as your -current PowerShell session is active. +Store your domain admin credentials in the `$Cred` variable. This approach allows you to enter your +credentials once and reuse them on a per-command basis as long as your current PowerShell session +remains active. ```powershell $Cred = Get-Credential ``` -Create a one-to-one PowerShell remoting session to the domain controller named dc01. +Establish a one-to-one PowerShell remoting session to the domain controller named dc01. ```powershell Enter-PSSession -ComputerName dc01 -Credential $Cred ``` +Notice the PowerShell prompt is preceded by `[dc01]`. This prefix indicates you're in an interactive +session with the remote computer named dc01. Any commands you run now execute on dc01, not your +local machine. + ```Output [dc01]: PS C:\Users\Administrator\Documents> ``` -Notice that in the previous example that the PowerShell prompt is preceded by `[dc01]`. This means -you're in an interactive PowerShell session to the remote computer named dc01. Any commands you -execute run on dc01, not on your local computer. Also, keep in mind that you only have access to the -PowerShell commands that exist on the remote computer and not the ones on your local computer. In -other words, if you've installed additional modules on your computer, they aren't accessible on the -remote computer. +Remember that you can only access the PowerShell commands and modules installed on the remote +computer. If you installed other modules locally, they aren't available in the remote session. -When you're connected to a remote computer via a one-to-one interactive PowerShell remoting session, -you're effectively sitting at the remote computer. The objects are normal objects just like the ones -you've been working with throughout this entire book. +When connected via a one-to-one interactive remoting session, it's as if you're sitting directly at +the remote machine. ```powershell -[dc01]: Get-Process | Get-Member +[dc01]: Get-Process | Get-Member ``` ```Output @@ -130,33 +127,33 @@ PM AliasProperty PM = PagedMemorySize64 SI AliasProperty SI = SessionId VM AliasProperty VM = VirtualMemorySize64 WS AliasProperty WS = WorkingSet64 -Disposed Event System.EventHandler Disposed(System.Object, ... -ErrorDataReceived Event System.Diagnostics.DataReceivedEventHandler ... -Exited Event System.EventHandler Exited(System.Object, Sy... -OutputDataReceived Event System.Diagnostics.DataReceivedEventHandler ... +Disposed Event System.EventHandler Disposed(Sy... +ErrorDataReceived Event System.Diagnostics.DataReceived... +Exited Event System.EventHandler Exited(Syst... +OutputDataReceived Event System.Diagnostics.DataReceived... BeginErrorReadLine Method void BeginErrorReadLine() BeginOutputReadLine Method void BeginOutputReadLine() CancelErrorRead Method void CancelErrorRead() CancelOutputRead Method void CancelOutputRead() Close Method void Close() CloseMainWindow Method bool CloseMainWindow() -CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(... -Dispose Method void Dispose(), void IDisposable.Dispose() +CreateObjRef Method System.Runtime.Remoting.ObjRef ... +Dispose Method void Dispose(), void IDisposabl... Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetLifetimeService Method System.Object GetLifetimeService() GetType Method type GetType() -InitializeLifetimeService Method System.Object InitializeLifetimeService() +InitializeLifetimeService Method System.Object InitializeLifetim... Kill Method void Kill() Refresh Method void Refresh() Start Method bool Start() ToString Method string ToString() -WaitForExit Method bool WaitForExit(int milliseconds), void Wai... -WaitForInputIdle Method bool WaitForInputIdle(int milliseconds), boo... +WaitForExit Method bool WaitForExit(int millisecon... +WaitForInputIdle Method bool WaitForInputIdle(int milli... __NounName NoteProperty string __NounName=Process BasePriority Property int BasePriority {get;} -Container Property System.ComponentModel.IContainer Container {... -EnableRaisingEvents Property bool EnableRaisingEvents {get;set;} +Container Property System.ComponentModel.IContaine... +EnableRaisingEvents Property bool EnableRaisingEvents {get;s... ExitCode Property int ExitCode {get;} ExitTime Property datetime ExitTime {get;} Handle Property System.IntPtr Handle {get;} @@ -164,77 +161,85 @@ HandleCount Property int HandleCount {get;} HasExited Property bool HasExited {get;} Id Property int Id {get;} MachineName Property string MachineName {get;} -MainModule Property System.Diagnostics.ProcessModule MainModule ... -MainWindowHandle Property System.IntPtr MainWindowHandle {get;} +MainModule Property System.Diagnostics.ProcessModul... +MainWindowHandle Property System.IntPtr MainWindowHandle ... MainWindowTitle Property string MainWindowTitle {get;} -MaxWorkingSet Property System.IntPtr MaxWorkingSet {get;set;} -MinWorkingSet Property System.IntPtr MinWorkingSet {get;set;} -Modules Property System.Diagnostics.ProcessModuleCollection M... -NonpagedSystemMemorySize Property int NonpagedSystemMemorySize {get;} -NonpagedSystemMemorySize64 Property long NonpagedSystemMemorySize64 {get;} +MaxWorkingSet Property System.IntPtr MaxWorkingSet {ge... +MinWorkingSet Property System.IntPtr MinWorkingSet {ge... +Modules Property System.Diagnostics.ProcessModul... +NonpagedSystemMemorySize Property int NonpagedSystemMemorySize {g... +NonpagedSystemMemorySize64 Property long NonpagedSystemMemorySize64... PagedMemorySize Property int PagedMemorySize {get;} PagedMemorySize64 Property long PagedMemorySize64 {get;} PagedSystemMemorySize Property int PagedSystemMemorySize {get;} -PagedSystemMemorySize64 Property long PagedSystemMemorySize64 {get;} +PagedSystemMemorySize64 Property long PagedSystemMemorySize64 {g... PeakPagedMemorySize Property int PeakPagedMemorySize {get;} PeakPagedMemorySize64 Property long PeakPagedMemorySize64 {get;} PeakVirtualMemorySize Property int PeakVirtualMemorySize {get;} -PeakVirtualMemorySize64 Property long PeakVirtualMemorySize64 {get;} +PeakVirtualMemorySize64 Property long PeakVirtualMemorySize64 {g... PeakWorkingSet Property int PeakWorkingSet {get;} PeakWorkingSet64 Property long PeakWorkingSet64 {get;} -PriorityBoostEnabled Property bool PriorityBoostEnabled {get;set;} -PriorityClass Property System.Diagnostics.ProcessPriorityClass Prio... +PriorityBoostEnabled Property bool PriorityBoostEnabled {get;... +PriorityClass Property System.Diagnostics.ProcessPrior... PrivateMemorySize Property int PrivateMemorySize {get;} PrivateMemorySize64 Property long PrivateMemorySize64 {get;} -PrivilegedProcessorTime Property timespan PrivilegedProcessorTime {get;} +PrivilegedProcessorTime Property timespan PrivilegedProcessorTim... ProcessName Property string ProcessName {get;} -ProcessorAffinity Property System.IntPtr ProcessorAffinity {get;set;} +ProcessorAffinity Property System.IntPtr ProcessorAffinity... Responding Property bool Responding {get;} -SafeHandle Property Microsoft.Win32.SafeHandles.SafeProcessHandl... +SafeHandle Property Microsoft.Win32.SafeHandles.Saf... SessionId Property int SessionId {get;} -Site Property System.ComponentModel.ISite Site {get;set;} -StandardError Property System.IO.StreamReader StandardError {get;} -StandardInput Property System.IO.StreamWriter StandardInput {get;} -StandardOutput Property System.IO.StreamReader StandardOutput {get;} -StartInfo Property System.Diagnostics.ProcessStartInfo StartInf... +Site Property System.ComponentModel.ISite Sit... +StandardError Property System.IO.StreamReader Standard... +StandardInput Property System.IO.StreamWriter Standard... +StandardOutput Property System.IO.StreamReader Standard... +StartInfo Property System.Diagnostics.ProcessStart... StartTime Property datetime StartTime {get;} -SynchronizingObject Property System.ComponentModel.ISynchronizeInvoke Syn... -Threads Property System.Diagnostics.ProcessThreadCollection T... +SynchronizingObject Property System.ComponentModel.ISynchron... +Threads Property System.Diagnostics.ProcessThrea... TotalProcessorTime Property timespan TotalProcessorTime {get;} UserProcessorTime Property timespan UserProcessorTime {get;} VirtualMemorySize Property int VirtualMemorySize {get;} VirtualMemorySize64 Property long VirtualMemorySize64 {get;} WorkingSet Property int WorkingSet {get;} WorkingSet64 Property long WorkingSet64 {get;} -PSConfiguration PropertySet PSConfiguration {Name, Id, PriorityClass, Fi... -PSResources PropertySet PSResources {Name, Id, Handlecount, WorkingS... -Company ScriptProperty System.Object Company {get=$this.Mainmodule.... -CPU ScriptProperty System.Object CPU {get=$this.TotalProcessorT... -Description ScriptProperty System.Object Description {get=$this.Mainmod... -FileVersion ScriptProperty System.Object FileVersion {get=$this.Mainmod... -Path ScriptProperty System.Object Path {get=$this.Mainmodule.Fil... -Product ScriptProperty System.Object Product {get=$this.Mainmodule.... -ProductVersion ScriptProperty System.Object ProductVersion {get=$this.Main... -[dc01]: +PSConfiguration PropertySet PSConfiguration {Name, Id, Prio... +PSResources PropertySet PSResources {Name, Id, Handleco... +Company ScriptProperty System.Object Company {get=$thi... +CPU ScriptProperty System.Object CPU {get=$this.To... +Description ScriptProperty System.Object Description {get=... +FileVersion ScriptProperty System.Object FileVersion {get=... +Path ScriptProperty System.Object Path {get=$this.M... +Product ScriptProperty System.Object Product {get=$thi... +ProductVersion ScriptProperty System.Object ProductVersion {g... ``` -When you're done working with the remote computer, exit the one-to-one remoting session by using the -`Exit-PSSession` cmdlet. +When you finish working with the remote computer, run the `Exit-PSSession` cmdlet to end the remote +session. ```powershell [dc01]: Exit-PSSession ``` -## One-To-Many Remoting +## One-to-many remoting -Sometimes you may need to perform a task interactively on a remote computer. But remoting is much -more powerful when performing a task on multiple remote computers at the same time. Use the -`Invoke-Command` cmdlet to run a command against one or more remote computers at the same time. +While you might occasionally need to perform tasks interactively on a remote computer, PowerShell +remoting becomes more powerful when you simultaneously execute commands across multiple remote +systems. Use the `Invoke-Command` cmdlet to run commands on one or more remote computers at the same +time. + +In the following example, you query three servers for the status of the Windows Time service. The +`Get-Service` cmdlet is placed inside the script block of `Invoke-Command`, meaning it executes on +each remote computer. ```powershell -Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred +Invoke-Command -ComputerName dc01, sql02, web01 { + Get-Service -Name W32time +} -Credential $Cred ``` +The results are returned to your local session as deserialized objects. + ```Output Status Name DisplayName PSComputerName ------ ---- ----------- -------------- @@ -243,15 +248,12 @@ Start... W32time Windows Time dc01 Running W32time Windows Time sql02 ``` -In the previous example, three servers were queried for the status of the Windows Time service. The -`Get-Service` cmdlet was placed inside the script block of `Invoke-Command`. `Get-Service` actually -runs on the remote computer and the results are returned to your local computer as deserialized -objects. - -Piping the previous command to `Get-Member` shows that the results are indeed deserialized objects. +To confirm the returned objects are deserialized, pipe the output to `Get-Member`. ```powershell -Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred | Get-Member +Invoke-Command -ComputerName dc01, sql02, web01 { + Get-Service -Name W32time +} -Credential $Cred | Get-Member ``` ```Output @@ -260,41 +262,47 @@ Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Cre Name MemberType Definition ---- ---------- ---------- GetType Method type GetType() -ToString Method string ToString(), string ToString(string format, Sys... +ToString Method string ToString(), string ToString(strin... Name NoteProperty string Name=W32time -PSComputerName NoteProperty string PSComputerName=sql02 +PSComputerName NoteProperty string PSComputerName=dc01 PSShowComputerName NoteProperty bool PSShowComputerName=True -RequiredServices NoteProperty Deserialized.System.ServiceProcess.ServiceController[... -RunspaceId NoteProperty guid RunspaceId=570313c4-ac84-4109-bf67-c6b33236af0a +RequiredServices NoteProperty Deserialized.System.ServiceProcess.Servi... +RunspaceId NoteProperty guid RunspaceId=5ed06925-8037-43ef-9072-... CanPauseAndContinue Property System.Boolean {get;set;} CanShutdown Property System.Boolean {get;set;} CanStop Property System.Boolean {get;set;} Container Property {get;set;} -DependentServices Property Deserialized.System.ServiceProcess.ServiceController[... +DependentServices Property Deserialized.System.ServiceProcess.Servi... DisplayName Property System.String {get;set;} MachineName Property System.String {get;set;} ServiceHandle Property System.String {get;set;} ServiceName Property System.String {get;set;} -ServicesDependedOn Property Deserialized.System.ServiceProcess.ServiceController[... +ServicesDependedOn Property Deserialized.System.ServiceProcess.Servi... ServiceType Property System.String {get;set;} Site Property {get;set;} StartType Property System.String {get;set;} Status Property System.String {get;set;} ``` -Notice that the majority of the methods are missing on deserialized objects. This means they're not -live objects; they're inert. You can't start or stop a service using a deserialized object because -it's a snapshot of the state of that object the point when the command ran on the remote computer. +Notice that most methods are missing from deserialized objects. The methods are missing because +these objects aren't live. They're inert snapshots of the object's state when you execute the +command against the remote computer. For example, you can't start or stop a service using a +deserialized object since it no longer has access to the required methods. -That doesn't mean you can't start or stop a service using a method with `Invoke-Command` though. It -just means that the method has to be called in the remote session. +However, this doesn't mean you can't use methods like `Stop()` with `Invoke-Command`. The key is +that you must call the method within the remote session. -I'll stop the Windows Time service on all three of those remote servers using the **Stop()** method -to prove this point. +To demonstrate, stop the Windows Time service on all three remote servers by invoking the `Stop()` +method remotely. ```powershell -Invoke-Command -ComputerName dc01, sql02, web01 {(Get-Service -Name W32time).Stop()} -Credential $Cred -Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred +Invoke-Command -ComputerName dc01, sql02, web01 { + (Get-Service -Name W32time).Stop() +} -Credential $Cred + +Invoke-Command -ComputerName dc01, sql02, web01 { + Get-Service -Name W32time +} -Credential $Cred ``` ```Output @@ -305,31 +313,33 @@ Stopped W32time Windows Time dc01 Stopped W32time Windows Time sql02 ``` -As mentioned in a previous chapter, if a cmdlet exists for accomplishing a task, I recommend using -it instead of using a method. In the previous scenario, I recommend using the `Stop-Service` cmdlet -instead of the stop method. I chose to use the **Stop()** method to prove a point since many people -are under the misconception that methods can't be called when using PowerShell remoting. They can't -be called on the object that's returned because it's deserialized, but they can be called in the -remote session itself. +As mentioned in an earlier chapter, if there's a cmdlet available to accomplish a task, it's +preferable to use it rather than calling a method directly. For example, use the `Stop-Service` +cmdlet instead of the `Stop()` method to stop a service. -## PowerShell Sessions +In the previous example, the `Stop()` method is used to make a point. Some people mistakenly believe +that you can't use methods with PowerShell remoting. While it's true that you can't call methods on +deserialized objects returned to your local session, you can, however, invoke them within the remote +session. -In the last example in the previous section, I ran two commands using the `Invoke-Command` cmdlet. -That means two separate sessions had to be set up and torn down to run those two commands. +## PowerShell sessions -Similar to the CIM sessions discussed in Chapter 7, a PowerShell session to a remote computer can be -used to run multiple commands against the remote computer without the overhead of a new session for -each individual command. +In the final example from the previous section, you ran two commands using the `Invoke-Command` +cmdlet. This scenario resulted in two separate sessions being established and torn down. One for +each command. -Create a PowerShell session to each of the three computers we've been working with in this chapter, +Like CIM sessions, a persistent PowerShell session allows you to run multiple commands against a +remote computer without the overhead of creating a new session for each command. + +Create a PowerShell session to each of the three computers you're working with in this chapter, DC01, SQL02, and WEB01. ```powershell $Session = New-PSSession -ComputerName dc01, sql02, web01 -Credential $Cred ``` -Now use the variable named `$Session` to start the Windows Time service using a method and check the -status of the service. +Now, use the `$Session` variable to start the Windows Time service by calling its method and then +verify the service status. ```powershell Invoke-Command -Session $Session {(Get-Service -Name W32time).Start()} @@ -344,10 +354,10 @@ Start... W32time Windows Time dc01 Running W32time Windows Time sql02 ``` -Once the session is created using alternate credentials, it's no longer necessary to specify the -credentials each time a command is run. +Once you create the session with alternate credentials, you don't need to specify those credentials +again for each command. -When you're finished using the sessions, be sure to remove them. +Be sure to remove the sessions when you finish using them. ```powershell Get-PSSession | Remove-PSSession @@ -355,34 +365,35 @@ Get-PSSession | Remove-PSSession ## Summary -In this chapter you've learned about PowerShell remoting, how to run commands in an interactive -session with one remote computer, and how to run commands against multiple computers using -one-to-many remoting. You've also learned the benefits of using a PowerShell session when running -multiple commands against the same remote computer. +In this chapter, you learned the fundamentals of PowerShell remoting, including running commands +interactively on a single remote computer and executing commands across multiple systems using +one-to-many remoting. You also explored the advantages of using persistent PowerShell sessions when +running multiple commands against the same remote computer. ## Review 1. How do you enable PowerShell remoting? -1. What is the PowerShell command for starting an interactive session with a remote computer? -1. What is a benefit of using a PowerShell remoting session versus just specifying the computer name +1. What PowerShell command do you use to start an interactive session with a remote computer? +1. What's one benefit of using a PowerShell remoting session instead of specifying the computer name with each command? -1. Can a PowerShell remoting session be used with a one-to-one remoting session? -1. What is the difference in the type of objects that are returned by cmdlets versus those returned - when running those same cmdlets against remote computers with `Invoke-Command`? +1. Can you use a PowerShell session in a one-to-one interactive remoting scenario? +1. What's the difference between the objects returned by cmdlets run locally and objects returned + when the same cmdlets are executed on remote computers using `Invoke-Command`? -## Recommended Reading +## References -- [about_Remote][about_Remote] -- [about_Remote_Output][about_Remote_Output] -- [about_Remote_Requirements][about_Remote_Requirements] -- [about_Remote_Troubleshooting][about_Remote_Troubleshooting] -- [about_Remote_Variables][about_Remote_Variables] -- [PowerShell Remoting FAQ][PowerShell Remoting FAQ] +- [about_Remote][about-remote] +- [about_Remote_Output][about-remote-output] +- [about_Remote_Requirements][about-remote-requirements] +- [about_Remote_Troubleshooting][about-remote-troubleshooting] +- [about_Remote_Variables][about-remote-variables] +- [PowerShell Remoting FAQ][remoting-faq] -[PowerShell Remoting FAQ]: ../../security/remoting/powershell-remoting-faq.yml -[about_Remote]: /powershell/module/microsoft.powershell.core/about/about_remote -[about_Remote_Output]: /powershell/module/microsoft.powershell.core/about/about_remote_output -[about_Remote_Requirements]: /powershell/module/microsoft.powershell.core/about/about_remote_requirements -[about_Remote_Troubleshooting]: /powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting -[about_Remote_Variables]: /powershell/module/microsoft.powershell.core/about/about_remote_variables + +[about-remote]: /powershell/module/microsoft.powershell.core/about/about_remote +[about-remote-output]: /powershell/module/microsoft.powershell.core/about/about_remote_output +[about-remote-requirements]: /powershell/module/microsoft.powershell.core/about/about_remote_requirements +[about-remote-troubleshooting]: /powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting +[about-remote-variables]: /powershell/module/microsoft.powershell.core/about/about_remote_variables +[remoting-faq]: /powershell/scripting/learn/remoting/powershell-remoting-faq