{"id":7712,"date":"2020-09-30T14:20:40","date_gmt":"2020-09-30T18:20:40","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=7712"},"modified":"2020-09-30T15:52:06","modified_gmt":"2020-09-30T19:52:06","slug":"answering-the-wsman-powershell-challenge","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/","title":{"rendered":"Answering the WSMan PowerShell Challenge"},"content":{"rendered":"\n<p>Today, I thought I'd share my solution to a recent <a href=\"https:\/\/ironscripter.us\/a-powershell-session-challenge\/\" target=\"_blank\" rel=\"noopener noreferrer\">Iron Scripter challenge<\/a>. I thought this was a fascinating task and one with a practical result.\u00a0 I'd encourage you to try your hand at the challenge and come back later to see how I tackled it.<\/p>\n\n\n\n<p>The challenge is not only a good test of your PowerShell scripting skills but also a test of how well you understand PowerShell remoting.\u00a0 In the long run, I have no doubt that PowerShell remoting will mean SSH. But that isn't coming anytime soon. Traditional PowerShell remoting using WSMan is still the way most IT Pros manage remote servers. This means you should understand it and be able to manage it.<\/p>\n\n\n\n<p>The scripting challenge was to create a tool that would query a remote server for WSMan connections and write a custom object to the pipeline with specific pieces of information. Here's how I approached this.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Know Your Processes<\/h2>\n\n\n\n<p>The first thing to know is that when a PowerShell remoting connection is established, it runs in a <em>wsmprovhost<\/em> process. Querying for this process is simple.<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1196\" height=\"306\" class=\"alignnone size-full wp-image-7713\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png\" alt=\"wsmprovhost\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png 1196w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-300x77.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-1024x262.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-768x196.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-850x217.png 850w\" sizes=\"auto, (max-width: 1196px) 100vw, 1196px\" \/>I could also have used <strong>Get-CimInstance<\/strong>. A useful feature of <strong>Get-Process<\/strong> is the ability to get the process owner, or username, for each process. However, this only works when<strong> Get-Process<\/strong> is run <em><strong>on<\/strong><\/em> the remote host. No problem. I can use <strong>Invoke-Command<\/strong>.<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1198\" height=\"185\" class=\"alignnone size-full wp-image-7714\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-owner.png\" alt=\"wsmprovhost-owner\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-owner.png 1198w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-owner-300x46.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-owner-1024x158.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-owner-768x119.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost-owner-850x131.png 850w\" sizes=\"auto, (max-width: 1198px) 100vw, 1198px\" \/> I'm filtering out the process ID of the <em>wsmprovhost <\/em>process that is temporarily created by <strong>Invoke-Command<\/strong>. The process is transient in this situation, but if I was using an existing PSSession to see who else was connected, I want to filter it out. That was one of the challenge criteria as well.<\/p>\n\n\n\n<p>The process object can provide a number of pieces of information the challenge was looking for. Although, one of the requirements was to get associated child processes. I found using <strong>Get-CimInstance<\/strong> to be useful for this task.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1043\" height=\"166\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/childprocess.png\" alt=\"childprocess\" class=\"wp-image-7715\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/childprocess.png 1043w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/childprocess-300x48.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/childprocess-1024x163.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/childprocess-768x122.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/childprocess-850x135.png 850w\" sizes=\"auto, (max-width: 1043px) 100vw, 1043px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Get-WSManInstance<\/h2>\n\n\n\n<p>The other parts of the challenge require a bit more effort.\u00a0 When a PowerShell remoting connection is established, there is a corresponding WSMan instance. As you may know, when you connect via PowerShell remoting, you are connecting to a session endpoint. The Get-PSSessionConfiguration cmdlet displays these endpoints. Almost always, these endpoints initiate a PowerShell session on the remote computer. In WSMan-speak, this runs in a shell.<\/p>\n\n\n\n<p>PowerShell has a cmdlet called <strong>Get-WSManInstance<\/strong> that allows you to enumerate these connections. <img loading=\"lazy\" decoding=\"async\" width=\"1056\" height=\"727\" class=\"alignnone size-full wp-image-7716\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmaninstance.png\" alt=\"wsmaninstance\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmaninstance.png 1056w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmaninstance-300x207.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmaninstance-1024x705.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmaninstance-768x529.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmaninstance-850x585.png 850w\" sizes=\"auto, (max-width: 1056px) 100vw, 1056px\" \/>As you can see, there is some useful information. One of the challenge tasks was to get the shell runtime. That is listed here but because this result is essentially an XML document, it isn't in a friendly format.<\/p>\n\n\n\n<p>Fortunately, there is an XML method that will convert these values.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1177\" height=\"764\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/convert-lexical.png\" alt=\"convert-lexical\" class=\"wp-image-7717\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/convert-lexical.png 1177w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/convert-lexical-300x195.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/convert-lexical-1024x665.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/convert-lexical-768x499.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/convert-lexical-850x552.png 850w\" sizes=\"auto, (max-width: 1177px) 100vw, 1177px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Get-PSRemoteSessionUser<\/h2>\n\n\n\n<p>Those where the tricky bits. Tasks like getting the source hostname from the IP address is easy with <strong>Resolve-DNSName<\/strong>. With all of this in mind, I wrote a PowerShell function called <strong><em>Get-PSRemoteSessionUser<\/em><\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Function Get-PSRemoteSessionUser {\n    [cmdletbinding(DefaultParameterSetName = \"ComputerName\")]\n    Param(\n        [Parameter(ParameterSetName = 'Session', Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [System.Management.Automation.Runspaces.PSSession[]]$Session,\n\n        [Parameter(ParameterSetName = 'ComputerName', Mandatory, Position = 0)]\n        [Alias('Cn')]\n        [ValidateNotNullOrEmpty()]\n        [string[]]$ComputerName,\n\n        [Parameter(ParameterSetName = 'ComputerName', ValueFromPipelineByPropertyName)]\n        [pscredential]$Credential,\n\n        [Parameter(ParameterSetName = 'ComputerName')]\n        [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication,\n\n        [Parameter(ParameterSetName = 'ComputerName')]\n        [Parameter(ParameterSetName = 'Session')]\n        [int]$ThrottleLimit\n    )\n\n    Begin {\n        Write-Verbose \"[BEGIN  ] Starting: $($MyInvocation.Mycommand)\"\n        #define the scriptblock to run remotely\n\n        $run = {\n            $VerbosePreference = $using:VerbosePreference\n            Write-Verbose \"[$([environment]::machinename)] Querying for local WSMan sessions\"\n            $process = 'wsmprovhost'\n\n            #these helper functions will be used to get and format connection data\n            Function _enumWsMan {\n                [cmdletbinding()]\n                Param()\n\n                Get-WSManInstance -ResourceURI Shell -Enumerate |\n                    Select-Object -Property Name, State, ShellID, Owner, ClientIP, ProcessID,\n                    @{Name = \"Memory\"; Expression = { _parseMemoryString $_.memoryUsed } },\n                    @{Name = \"ShellRunTime\"; Expression = { [System.Xml.XmlConvert]::ToTimeSpan($_.ShellRunTime) } },\n                    @{Name = \"ShellInactivity\"; Expression = { [System.Xml.XmlConvert]::ToTimeSpan($_.ShellInactivity) } },\n                    @{Name = \"MaxIdleTimeout\"; Expression = { [System.Xml.XmlConvert]::ToTimeSpan($_.MaxIdleTimeout) } },\n                    @{Name = \"SessionConfiguration\"; Expression = { Split-Path -path $_.resourceuri -leaf } }\n\n            }\n            Function _parseMemoryString {\n                #convert values like 11MB to 11534336\n                [cmdletbinding()]\n                Param([string]$StringValue)\n\n                switch -Regex ($StringValue ) {\n                    \"\\d+KB\" {\n                        $val = 1KB\n                    }\n                    \"\\d+MB\" {\n                        $val = 1MB\n                    }\n                    \"\\d+GB\" {\n                        $val = 1GB\n                    }\n\n                } #switch\n                if ($val) {\n                    [int]$i = ([regex]\"\\d+\").Match($StringValue).value\n                    $i * $val\n                }\n                else {\n                    Write-Warning \"Failed to parse $StringValue\"\n                    $stringValue\n                }\n\n            } #close function\n\n            try {\n                Write-Verbose \"[$([environment]::machinename)] Getting $process process excluding id $PID\"\n                $p = (Get-Process -Name $process -IncludeUserName -erroraction stop).where({ $_.id -ne $pid })\n            }\n            Catch [Microsoft.PowerShell.Commands.ProcessCommandException] {\n                Write-Warning \"Could not find process $process on this computer.\"\n            }\n            Catch {\n                Throw $_\n            }\n\n            if ($p) {\n\n                foreach ($item in $p) {\n\n                    if ($item.username) {\n                        Write-Verbose \"[$([environment]::machinename)] Getting the SID for $($item.username)\"\n                        $SID = [System.Security.Principal.NTAccount]::new(\"$($item.username)\").Translate([System.Security.Principal.SecurityIdentifier]).value\n                    }\n                    else {\n                        $SID = $null\n                    }\n                    #call a private function to enumerate WSMan connection associated with this process ID\n                    Write-Verbose \"[$([environment]::machinename)] Enumerating WSMan connections\"\n                    $connData = $(_enumWsMan).where({ $_.processid -eq $item.ID })\n\n                    #get child process IDs\n                    Write-Verbose \"[$([environment]::machinename)] Getting child processes for id $($item.id)\"\n                    $childProcs = (Get-CimInstance -ClassName win32_process -filter \"ParentProcessId = $($item.id)\" -Property ProcessID).ProcessID\n\n                    #resolve the hostname\n                    #temporarily disable Verbose to eliminate verbose messages from loading the DNSClient module\n                    $VerbosePreference = \"SilentlyContinue\"\n                    Import-Module DNSClient\n                    $VerbosePreference = $using:VerbosePreference\n                    Try {\n                        Write-Verbose \"[$([environment]::machinename)] Resolving the hostname for $($conndata.ClientIP)\"\n                        $rHost = (Resolve-DnsName -Name $connData.ClientIP -ErrorAction Stop).NameHost\n                    }\n                    Catch {\n                        Write-Verbose \"[$([environment]::machinename)] Failed to resolve a hostname for $($connData.ClientIP).\"\n                        $rHost = $connData.clientIP\n                    }\n                     Write-Verbose \"[$([environment]::machinename)] Returning connection data\"\n                    #Send data back to the host to construct a custom object\n                    @{\n                        rHost        = $rHost\n                        Item         = $item\n                        SID          = $SID\n                        Computername = [environment]::MachineName\n                        ChildProcs   = $childProcs\n                        ConnData     = $connData\n                    }\n\n                } #foreach item\n            }\n            else {\n                Write-Verbose \"[$([environment]::machinename)] No running $process process(e$as) found\"\n            }\n        } #close scriptblock\n\n        $PSBoundParameters.add(\"Scriptblock\", $Run)\n        $PSBoundParameters.Add(\"HideComputername\", $True)\n    } #begin\n\n    Process {\n        Write-Verbose \"[PROCESS] Getting remote connection data\"\n        $data = Invoke-Command @PSBoundParameters\n        foreach ($result in $data) {\n            Write-Verbose \"[PROCESS] Processing data for $($result.computername)\"\n            [pscustomobject]@{\n                PSTypename           = \"PSRemoteSessionUser\"\n                Computername         = $result.Computername\n                DateUTC              = (Get-Date).ToUniversalTime()\n                StartTimeUTC         = $result.item.StartTime.ToUniversalTime()\n                ProcessID            = $result.item.id\n                ChildProcesses       = $result.childProcs\n                Username             = $result.item.Username\n                SID                  = $result.sid\n                State                = $result.connData.State\n                RemoteHost           = $result.rHost\n                RemoteIPAddress      = $result.connData.ClientIP\n                ShellRunTime         = $result.conndata.ShellRunTime\n                SessionConfiguration = $result.connData.SessionConfiguration\n                Memory               = $result.connData.Memory\n            }\n        } #foreach result\n    } #process\n\n    End {\n        Write-Verbose \"[END    ] Ending: $($MyInvocation.Mycommand)\"\n    } #end\n\n} #close Get-RemoteSessionUser<\/code><\/pre>\n\n\n\n<p>The function is designed to let me query remote computers by name or through an existing session. If I use an existing session, it will be filtered out from the results. Most of the core querying happens remotely. The \"raw\" data is returned to the local host from <strong>Invoke-Command<\/strong> and turned into a custom object.<\/p>\n\n\n\n<p>My function uses verbose output and even passes my verbose preference to the remote computer.<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7718\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1.png\" alt=\"get-psremotesessionuser-1\" width=\"1999\" height=\"1067\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1.png 1999w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1-300x160.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1-1024x547.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1-768x410.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1-1536x820.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-1-850x454.png 850w\" sizes=\"auto, (max-width: 1999px) 100vw, 1999px\" \/>What did I get back?<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7719\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2.png\" alt=\"get-psremotesessionuser-2\" width=\"1999\" height=\"1067\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2.png 1999w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2-300x160.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2-1024x547.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2-768x410.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2-1536x820.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-2-850x454.png 850w\" sizes=\"auto, (max-width: 1999px) 100vw, 1999px\" \/>The custom object has properties that should meet all of the challenge requirements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Custom Formatting<\/h2>\n\n\n\n<p>But there is one more thing. The last part of the challenge was to create a custom formatting file. The results I have a great, but maybe I typically only need to see a formatted subset of properties. Using <a href=\"https:\/\/github.com\/jdhitsolutions\/PSScriptTools\/blob\/master\/functions\/New-PSFormatXML.ps1\" target=\"_blank\" rel=\"noopener noreferrer\">New-PSFormatXML<\/a> from the PSScriptTools module, I created a format.ps1xml. After a bit of tweaking in VS Code, I can load it into my session.<\/p>\n\n\n\n<pre class=\"wp-block-code lang:ps mark:0 decode:true\"><code lang=\"powershell\" class=\"language-powershell\">Update-FormatData psremotesessionuser.format.ps1xml<\/code><\/pre>\n\n\n\n<p>And now get nicely formatted results.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1516\" height=\"400\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-3.png\" alt=\"get-psremotesessionuser-3\" class=\"wp-image-7720\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-3.png 1516w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-3-300x79.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-3-1024x270.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-3-768x203.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-3-850x224.png 850w\" sizes=\"auto, (max-width: 1516px) 100vw, 1516px\" \/><\/figure>\n\n\n\n<p>Here's the format file.<\/p>\n\n\n\n<pre class=\"wp-block-code lang:ps mark:0 decode:true\"><code lang=\"xml\" class=\"language-xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?>\n&lt;!--\nformat type data generated 09\/15\/2020 08:54:32 by BOVINE320\\Jeff\nusing New-PSFormatXML from the PSScriptTools module.\n\nInstall-Module PSScriptTools\n-->\n&lt;Configuration>\n  &lt;ViewDefinitions>\n    &lt;View>\n      &lt;!--Created 09\/15\/2020 08:54:32 by BOVINE320\\Jeff-->\n      &lt;Name>default&lt;\/Name>\n      &lt;ViewSelectedBy>\n        &lt;TypeName>PSRemoteSessionUser&lt;\/TypeName>\n      &lt;\/ViewSelectedBy>\n      &lt;GroupBy>\n        &lt;PropertyName>Computername&lt;\/PropertyName>\n      &lt;\/GroupBy>\n      &lt;TableControl>\n        &lt;!--Delete the AutoSize node if you want to use the defined widths.-->\n        &lt;AutoSize \/>\n        &lt;TableHeaders>\n          &lt;TableColumnHeader>\n            &lt;Label>SessionConfiguration&lt;\/Label>\n            &lt;Width>23&lt;\/Width>\n            &lt;Alignment>left&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n          &lt;TableColumnHeader>\n            &lt;Label>Address&lt;\/Label>\n            &lt;Width>14&lt;\/Width>\n            &lt;Alignment>left&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n          &lt;TableColumnHeader>\n            &lt;Label>Username&lt;\/Label>\n            &lt;Width>15&lt;\/Width>\n            &lt;Alignment>left&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n          &lt;TableColumnHeader>\n            &lt;Label>State&lt;\/Label>\n            &lt;Width>12&lt;\/Width>\n            &lt;Alignment>left&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n          &lt;TableColumnHeader>\n            &lt;Label>Runtime&lt;\/Label>\n            &lt;Width>15&lt;\/Width>\n            &lt;Alignment>left&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n          &lt;TableColumnHeader>\n            &lt;Label>MemMB&lt;\/Label>\n            &lt;Width>12&lt;\/Width>\n            &lt;Alignment>right&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n          &lt;TableColumnHeader>\n            &lt;Label>PID&lt;\/Label>\n            &lt;Width>12&lt;\/Width>\n            &lt;Alignment>right&lt;\/Alignment>\n          &lt;\/TableColumnHeader>\n        &lt;\/TableHeaders>\n        &lt;TableRowEntries>\n          &lt;TableRowEntry>\n            &lt;TableColumnItems>\n              &lt;TableColumnItem>\n                &lt;PropertyName>SessionConfiguration&lt;\/PropertyName>\n              &lt;\/TableColumnItem>\n              &lt;TableColumnItem>\n                &lt;PropertyName>RemoteIPAddress&lt;\/PropertyName>\n              &lt;\/TableColumnItem>\n              &lt;TableColumnItem>\n                &lt;PropertyName>Username&lt;\/PropertyName>\n              &lt;\/TableColumnItem>\n              &lt;TableColumnItem>\n                &lt;PropertyName>State&lt;\/PropertyName>\n              &lt;\/TableColumnItem>\n              &lt;TableColumnItem>\n                &lt;PropertyName>ShellRunTime&lt;\/PropertyName>\n              &lt;\/TableColumnItem>\n              &lt;TableColumnItem>\n                &lt;ScriptBlock>$_.Memory\/.1MB -as [int]&lt;\/ScriptBlock>\n              &lt;\/TableColumnItem>\n              &lt;TableColumnItem>\n                &lt;PropertyName>ProcessID&lt;\/PropertyName>\n              &lt;\/TableColumnItem>\n            &lt;\/TableColumnItems>\n          &lt;\/TableRowEntry>\n        &lt;\/TableRowEntries>\n      &lt;\/TableControl>\n    &lt;\/View>\n  &lt;\/ViewDefinitions>\n&lt;\/Configuration><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Limitations<\/h2>\n\n\n\n<p>I now have a PowerShell tool I can run to see who has connections to servers and the state of those sessions.<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7721\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-4.png\" alt=\"get-psremotesessionuser-4\" width=\"1500\" height=\"682\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-4.png 1500w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-4-300x136.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-4-1024x466.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-4-768x349.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/get-psremotesessionuser-4-850x386.png 850w\" sizes=\"auto, (max-width: 1500px) 100vw, 1500px\" \/>Remember, this is only showing remote connections via WSMan. If someone is connected with SSH, or PowerShell Direct (to a virtual machine), I won't \"see\" them. But in my situation, those would be special use edge cases anyway.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Next Steps<\/h2>\n\n\n\n<p>I hope you tried your hand at the challenge and will keep an eye on the <a href=\"https:\/\/ironscripter.us\" target=\"_blank\" rel=\"noopener noreferrer\">Iron Scripter site<\/a> for future challenges. They are a great way to test your knowledge and expand your skills. If you are looking to learn a bit more about PowerShell, you might take a look at my <a href=\"https:\/\/pluralsight.pxf.io\/3D5av\" target=\"_blank\" rel=\"noopener noreferrer\">PowerShell Remoting Fundamentals<\/a> course from Pluralsight. Or visit my <a href=\"https:\/\/jdhitsolutions.com\/blog\/books-and-training\/\" target=\"_blank\" rel=\"noopener noreferrer\">Books and Training<\/a> page.<\/p>\n\n\n\n<p>I hope you found this informative and useful. Comments and feedback are always welcome.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I thought I&#8217;d share my solution to a recent Iron Scripter challenge. I thought this was a fascinating task and one with a practical result.\u00a0 I&#8217;d encourage you to try your hand at the challenge and come back later to see how I tackled it. The challenge is not only a good test of&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Now on the blog: Answering the WSMan #PowerShell Challenge","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[618,534,87,89],"class_list":["post-7712","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-iron-scripter","tag-powershell","tag-remoting","tag-wsman"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Answering the WSMan PowerShell Challenge &#8226; The Lonely Administrator<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Answering the WSMan PowerShell Challenge &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"Today, I thought I&#039;d share my solution to a recent Iron Scripter challenge. I thought this was a fascinating task and one with a practical result.\u00a0 I&#039;d encourage you to try your hand at the challenge and come back later to see how I tackled it. The challenge is not only a good test of...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2020-09-30T18:20:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-09-30T19:52:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Answering the WSMan PowerShell Challenge\",\"datePublished\":\"2020-09-30T18:20:40+00:00\",\"dateModified\":\"2020-09-30T19:52:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/\"},\"wordCount\":796,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/wsmprovhost.png\",\"keywords\":[\"Iron Scripter\",\"PowerShell\",\"remoting\",\"wsman\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/\",\"name\":\"Answering the WSMan PowerShell Challenge &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/wsmprovhost.png\",\"datePublished\":\"2020-09-30T18:20:40+00:00\",\"dateModified\":\"2020-09-30T19:52:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/wsmprovhost.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/09\\\/wsmprovhost.png\",\"width\":1196,\"height\":306},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7712\\\/answering-the-wsman-powershell-challenge\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Answering the WSMan PowerShell Challenge\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Answering the WSMan PowerShell Challenge &#8226; The Lonely Administrator","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/","og_locale":"en_US","og_type":"article","og_title":"Answering the WSMan PowerShell Challenge &#8226; The Lonely Administrator","og_description":"Today, I thought I'd share my solution to a recent Iron Scripter challenge. I thought this was a fascinating task and one with a practical result.\u00a0 I'd encourage you to try your hand at the challenge and come back later to see how I tackled it. The challenge is not only a good test of...","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/","og_site_name":"The Lonely Administrator","article_published_time":"2020-09-30T18:20:40+00:00","article_modified_time":"2020-09-30T19:52:06+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Answering the WSMan PowerShell Challenge","datePublished":"2020-09-30T18:20:40+00:00","dateModified":"2020-09-30T19:52:06+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/"},"wordCount":796,"commentCount":1,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png","keywords":["Iron Scripter","PowerShell","remoting","wsman"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/","name":"Answering the WSMan PowerShell Challenge &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png","datePublished":"2020-09-30T18:20:40+00:00","dateModified":"2020-09-30T19:52:06+00:00","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/09\/wsmprovhost.png","width":1196,"height":306},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7712\/answering-the-wsman-powershell-challenge\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Answering the WSMan PowerShell Challenge"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":347,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/347\/winrm-domain-or-workgroup\/","url_meta":{"origin":7712,"position":0},"title":"WinRM: Domain or Workgroup?","author":"Jeffery Hicks","date":"September 11, 2009","format":false,"excerpt":"I'm curious about something and would like to hear from you. PowerShell v2 remoting uses WinRM which in a domain environment is very secure and easy to use. You can even use a GPO to configure your domain members. However you can also use WinRM in a workgroup environment but\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":5895,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/5895\/another-look-at-powershell-core-version-information\/","url_meta":{"origin":7712,"position":1},"title":"Another Look at PowerShell Core Version Information","author":"Jeffery Hicks","date":"February 8, 2018","format":false,"excerpt":"As PowerShell Core begins to spread into our world, and as we start thinking about working and scripting cross-platform, it will be useful to know what type of platform you are running on. The built in $PSVersionTable is an obvious place to start. On PowerShell Core there are also some\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/02\/image_thumb-5.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/02\/image_thumb-5.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/02\/image_thumb-5.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":8499,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8499\/using-the-powershell-ise-as-a-remote-management-console\/","url_meta":{"origin":7712,"position":2},"title":"Using the PowerShell ISE as a Remote Management Console","author":"Jeffery Hicks","date":"July 20, 2021","format":false,"excerpt":"Way back before the days of PowerShell Core, or even VS Code for that matter, the PowerShell ISE was the center of my PowerShell world. I spent a lot of time finding ways to make it easier for me to use and to push it to its limits. Naturally, the\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/07\/ise-remotetab-form2.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":7347,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell-7\/7347\/powershell-7-remoting-cleanup\/","url_meta":{"origin":7712,"position":3},"title":"PowerShell 7 Remoting Cleanup","author":"Jeffery Hicks","date":"March 10, 2020","format":false,"excerpt":"Now that PowerShell 7 is here and hopefully installed on your Windows 10 desktop, you're good to go, right? I'd say you probably all set. However, if like me, you were running PowerShell 7 betas or had PowerShell Core also installed, a little housekeeping might be in order. I don't\u2026","rel":"","context":"In &quot;PowerShell 7&quot;","block_context":{"text":"PowerShell 7","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-7\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/03\/image_thumb-7.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/03\/image_thumb-7.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/03\/image_thumb-7.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/03\/image_thumb-7.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2935,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/2935\/get-ciminstance-from-powershell-2-0\/","url_meta":{"origin":7712,"position":4},"title":"Get CIMInstance from PowerShell 2.0","author":"Jeffery Hicks","date":"April 10, 2013","format":false,"excerpt":"I love the new CIM cmdlets in PowerShell 3.0. Querying WMI is a little faster because the CIM cmdlets query WMI using the WSMAN protocol instead of DCOM. The catch is that remote computers must be running PowerShell 3 which includes the latest version of the WSMAN protocol and the\u2026","rel":"","context":"In &quot;Powershell 3.0&quot;","block_context":{"text":"Powershell 3.0","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-3-0\/"},"img":{"alt_text":"get-ciminstance-error","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/04\/get-ciminstance-error-300x145.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":7047,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7047\/my-powershell-hyper-v-health-report\/","url_meta":{"origin":7712,"position":5},"title":"My PowerShell Hyper-V Health Report","author":"Jeffery Hicks","date":"December 5, 2019","format":false,"excerpt":"Over the last few years I've been using and tweaking a PowerShell script that generates an HTML report that provides information about a Hyper-V host and running virtual machines. This is another great use case for a PowerShell control script. The script helps me organize commands like Get-CimInstance, Get-VM and\u2026","rel":"","context":"In &quot;Hyper-V&quot;","block_context":{"text":"Hyper-V","link":"https:\/\/jdhitsolutions.com\/blog\/category\/hyper-v\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/12\/image_thumb-8.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/12\/image_thumb-8.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/12\/image_thumb-8.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/12\/image_thumb-8.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/7712","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=7712"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/7712\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=7712"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=7712"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=7712"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}