Working with the new System Path Editor in Server 2016 RTM

If I were to ask how many of you LIKE editing the System Path in Windows I’ll bet I wouldn’t see a lot of hands up in the room.  I specifically wrote a function in PowerShell to edit the path for that reason.

As the path grows it becomes difficult to manage.

In Windows Server 2016 RTM there is a new Path editor (And it’s very easy to find and use!)

Drill down to the Environment Variables as you would normally under “Advanced Settings”

image

 

When you go to view your paths, especially the SYSTEM Path there’s a new cool option, it brings up a nice GUI Editor.

image

“Wow! This makes editing the path WAY better!” I thought but watch out… it’s a new Feature with some “undocumented features”

If you Choose “Browse” to select a path you’ll notice something, it’s missing the extra ‘\’ which I found causes some applications to miss that folder in a Search

image

 

You can of course easily highlight the entry and add in the missing ‘\’

image

The other one to watch out for is the “New” button to Add an entry.   If you click on “New” and try to immediately Browse to a folder you’ll find it deletes the entry above it.

image

That can’t be good!

image

But the solution is easy.  Click “New” and begin typing something … ANYTHING in the new Field and THEN browse away… Just again remember to add in the that missing ‘\’ when you’re done.

It was actually this feature that caused me initial issues with PowerShell 6 Open Source in that I browsed for C:\Program Files\OpenSSH and the entry was missing a ‘\’ at the end.  This caused PowerShell to skip over the folder as a file when searching for SSH.EXE

Bug in OpenSource PowerShell PSRemoting (6 release 9 and 10) and Workaround

I’m doing a talk at MVPDAYS on Open Source PowerShell and one of the items I was most excited about I had to try… PowerShell remoting!

In the current release it’s still an interactive PowerShell session but it’s amazing what it will bring forth.   The option for a Windows Admin to remote to a Linux/macOS system with a PowerShell script from Windows!  Or simply to consume the text data from Linux and flip it to objects.   Natively converting Json and XML!

Or for the Linux admin stuck with some Windows Servers.  It means running your native Bash, firing up a PowerShell command to manage those Windows Servers the Business brought in… or in the long term using Cmdlets provided by Vendors like Dell to manage applicances…

It’s all about OPTIONS for the Admin.

But today I REALLY wanted to play with PowerShell remoting.   Jason Helmick showed it online with Jeffrey Snover and it really IS is.   Requirements are pretty simple too.

  • Open Source PowerShell at both endpoints
  • OpenSSH on a Linux / macOS
  • SSH_Win32 on Windows
  • Some minor configuration

And use is just as easy.

New-Pssession –hostname ComputerwithSSHServer –username whoeveryouare

After a password prompt you just connect and you’re in the OTHER side using PowerShell!

I had everything loaded up, the most current release of PowerShell from Github on Windows and Linux, Open SSH, followed the instructions to the letter and

bbbbzzzztt! nothing

Windows would not receive the open connection Linux with some weird cryptic error.  Linux could not receive from Windows.

Jason suggested the first thing which was “confirm SSH” works.   Which I did.    Pretty easy test too

SSH username@server

 

I poked about online and saw a reference from Microsoft regarding a bug in which the SSH_Win32 would drop a blank line with a successful connection in STDERR .   Since it was a recent bug and Jason had demoed the Open Source PowerShell with PSRemoting maybe a tad early than that… I guessed there might have been a bug somewhere about.

So stage one.  Rollback to PowerShell 6.0.0.9 and one version EARLIER of SSH_Win32.

Once I did THAT Linux happily connected to Windows via PowerShell Remoting!

But

…BUT

(yeah there’s always a But somewhere)

Windows still could not initiate the session.   Evil vile cryptic error message about he Endpoint having finished already. However in running through the troubleshooting (Running the SSHD in Diagnostic mode) I could see the connection didn’t FAIL it just NEVER ACTUALLY HAPPENED.

“That’s it! Pull out the big guns!  Mark Russinovich will LOVE THIS!  We’re going to use a Sysinternals tool to fix a buggy feature in PowerShell 6!”

Procmon.exe was downloaded.  I set it to only watch powershell.exe for events.   Cleared off the old events of course.

Started the New-Pssession –hostname eotubuntu –username energizedtech

Watched the fail

Stopped monitoring

Get rid of all the successes on the filter

Now…. LOOK

 

Drilling back the most recent set of entries I noticed a search through various folders for SSH.EXE and GET-SSH.EXE.  Including an interesting one.

‘C:\Program Files (x86)\Putty’

But I never had Putty on this server! It was a clean Server 2016 RTM.   Which told me…. (no no wait… looks like I did!)

Here’s the list it found

C:\Windows\system32
C:\Windows
C:\Windows\system32\wbem
C:\Windows\system32\WindowsPowerShell\1.0C:\Users\Administrator\Appdata\Local\Microsoft\Windows\Apps

But on Server 2016 it CLEARLY showed C:\Program Files\OpenSSH in the system path…. which was wrong.

It should ACTUALLY have been C:\Program Files\OpenSSH\ (Notice that extract Backslash? I DIDN’T)

So I re-edited the path to hold it and now it all works properly.

Why was it missing the Backslash?  I used the new “Browse for Path” feature in the Path Editor of Server 2016.   It did it.  Must be an undocumented feature.

With that change in place I could happily run PowerShell remoting from Windows to Linux or Linux back to Windows

….Can’t WAIT for Implicit Remoting !

Making the Configuration Manager PowerShell Module Discoverable

I’m not going to ENABLE-RANT today.   Anybody that uses System Center Configuration Manager knows one thing, you need to MANUALLY add in the Cmdlets to use them using this line

Import-Module ‘C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1’

True, it’s irritating that I can just do something like this in a modern server

Import-Module ConfigurationManager

If this were there not only would it be EASIER to access the module locally, it would also allow me to create and establish Remote PowerShell sessions to EASILY work with Configuration Manager and make Implicit remoting far smoother.

But rather than get upset, I decided to sit down and find out why.  Why if I do THIS

Get-Module –listavailable ConfigurationManager

Does it NOT find the module?

The answer was surprisingly easy (and a bit silly it got missed by somebody)

For your module to be discoverable it needs to follow two rules

  1. The PSD1 file must be in a folder of the same name
  2. This Folder must be added to the System Environment variable “PSModulePath”

So examining my default PSModulePath on a Configuration Manager 1606 server It was DEFINITELY not there (yes, fully patched, rebooted multiple times)

$ENV:PSModulePath

C:\Users\Administrator.SYSTEMCTR\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\

So initially I thought I would just add it to the PSModulePath in the following fashion while in a PowerShell prompt as Administrator.

$ENV:PSModulePath=($ENV:PSModulePath) + ‘;C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\’

Tried that and looked and still nothing…. oh right forgot the FIRST rule

The PSD1 file must be in a folder of the same name

Our problem is that all of the needed files and content exist in the BIN folder and it needs to be renamed to ConfigurationManager.  But obviously we can’t do THAT or things will break.  

We COULD just make a copy of that folder called “ConfigurationManager” and add THAT to the path.  That might work too. But that offers up other scary words.

  • “Supportability” (Microsoft probably won’t support that)
  • “Patching” (If it DID work, we’d have to dupe that folder EACH and EVERY TIME we patched)
  • “Works?” (Moving supporting Binaries in ANY major application is just Ripe with Risk)

The it dawned on me.  Since VISTA (Stop cringing) we’ve had Junctions.   A Junction is a “Pseudo Folder” which ACTS like a Directory but points off to another Directory.

We COULD create a Junction called “ConfigurationManager” and point it RIGHT BACK to the folder with all of the goodies needed in the Configuration Manager module.

Well guess what… it works! Here’s the Script in PowerShell to make this useful for you as well.

# Create a Junction to act as a folder called “Configuration Manager” pointing to the
# ‘Bin’ folder which has the Actual Configuration Manager module
# This provides a “Pseudo Folder” to match the Module Name needed

$TargetFolder=’C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\’
$TargetPath=’C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\PSModule\’

# Verify this has not been done yet, if it has go ahead
If (!(Test-Path “$($TargetPath)ConfigurationManager\”))
{
New-Item -ItemType Directory -Path $TargetPath –Force
CMD.EXE /C MKLINK /J “$($TargetPath)ConfigurationManager” $TargetFolder
# You can use this line INSTEAD of MKLINK if you are running
# PowerShell 5
#New-Item -ItemType Junction -Name ConfigurationManager -Value $TargetFolder -Path $TargetPath
}

# Permanently update the PSModulePath Environment variable
# With the parent path holding the Configuration Manager folder
# This will make it fully discoverable

$OldPSPath=(Get-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PSModulePath).PSModulePath

# Verify this has not been done yet, if it has go ahead
IF (!($OldPSPath | Select-String -SimpleMatch “$($TargetPath)ConfigurationManager”))
{
$NewPSPath=$OldPSPath+’;’+$TargetPath+’ConfigurationManager’
Set-ItemProperty -Path ‘Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment’ -Name PSModulePath –Value $NewPSPath
}
$ENV:PSModulePath=$NewPSPath

 

Now I can just run Import-Module ConfigurationManager and Woohoo! I’m off to races!

I’ll post this to the Technet Gallery later on.

Share and Enjoy!

Sean
The Energized Tech
Honorary Scripting Guy