$PROFILE and RDP Sessions

$PROFILE and RDP Sessions

Problem Statement: I need to RDP onto multiple machines in multiple labs for multiple projects. Each project has its own customizations to my $PROFILE. I need a way to keep all those files up-to-date and yet accessible.

Firstly, my desktop's $PROFILE isn't a good start - it has customizations for my dev environment, not my lab environments. And, while I've built huge Rube Goldberg machines of Gold+Diff scripts to differentiate environments, I've found those to be quite brittle. I'd rather take the hit of maintaining the four or five $PROFILEs for my lab environments separately.

While I can access local resources via the \\tsclient\c\users\timdunn share, that doesn't scale. In one lab, we access multiple AD domains by the same hop-box, so I'm C:\users\timdunn.DOMAIN1, C:\users\timdunn.DOMAIN2, etc. based on which AD domain I'm using for that session. That's not a concern importing my $PROFILE from my desktop to the hop-box, but it is a concern going from the hop-box to the various lab machines. I don't want to have kludge-logic to try to handle these one-offs.

Oh, and there's our sustaining engineering lab, which is still running Server 2003R2 (for the next fifteen months and counting). On that jump-box, my $HOME is D:\Documents and Settings\timdunn.SELAB.LOCAL Especially given that we see the sunset from here, I don't want kludge-logic to handle that environment. I want the same code to be able to handle all of these.

Subst.exe to the rescue. What I'll do is normalize on a virtual drive to map to $HOME, no matter what its name. That way, no matter which AD domain I'm using, that session will access \\tsclient\p to get to my desktop's $HOME, and it will provide the virtual drive P:\ to map to my jump-box session's $HOME.

===

Okay, now how about keeping the separate projects' files separate? Instead of my usual $PROFILE path, I'm going to create a folder directly under my $HOME to store this:

This means all my files are in the same place ($HOME\WindowsPowerShell), but separated by projects, and I have one single file that has all the stuff that I want in all my environments, such as Set-ConsoleSize, all the SSL / certificate stuff, etc.

===

How about the setup?

This is hardcoded to use $HOME\WindowsPowerShell\$ProjectName (I’m using ‘CorpNet’, but you’ll likely use something else, hence the variable name.) so you’ll need to create those folders.

Save the script below as $HOME\WindowsPowerShell\$ProjectName\Microsoft.PowerShell_profile.ps1 and edit it to replace ‘CorpNet’ with your appropriate project name. Configure and load the functions into the local PSH session with the following command:

. $PROFILE

This is going to bomb out because the .sha256 file is missing. No big dea. Let’s create it. Run the following:

This will load the clipboard with the necessary code snippet. (Paste it into a notepad.exe window if you want to double-check it.) In the RDP session, open a PSH window and right-click it into there.

Note that the last line is commented out. Up-arrow, Home, and uncomment it if you like how the rest of the snippet looks. Press [Enter] and it will back up your existing $PROFILE to "$PROFILE (datestamp)", copy Microsoft.PowerShell_profile.ps1 from "\\tsclient\p\WindowsPowerShell\$ProjectName” (which is really just “$HOME\WindowsPowerShell\$ProjectName\Microsoft.PowerShell_profile.ps1” on your desktop RDPing to the session) to $PROFILE, then dot in $PROFILE.

===

Now, let's talk replication. It's easy enough to compare datestamps and copy whichever is newer over the older, but I want it to go from one direction: from my desktop, out to my hop-box, and from there to the individual lab machines.

Now, we have a slightly prank-friendly culture in one of our labs, but I don't want anything there somehow making it back to the other labs. A bit of EFS and a rudimentary checksum will dissuade most attempts. If you need stronger security, there's always script-signing.

Note that EFS and roaming %USERPROFILE% folders do not play nicely.

===

Finally, there's the payload. The code below contains nothing that you would usually find in a $PROFILE - no hacks to change your $Host.UI.RawUI.WindowTitle or redefine function:\Prompt, etc. That's where the CommonFunctionLibrary.psm1 and ProjectFunctionLibrary.psm1 come in.

$PROFILE on all these boxes should not change once deployed. Any changes to the two FunctionLibrary.psm1 files, such as snippets from this blog, will be replicated out automatically. After each edit, make sure to re-generate the SHA hash, otherwise the system will flag it as a mismatch.

Just remember to . $PROFILE every so often to push the changes through if you keep your PSH windows open overnight.