Safely storing credentials and other things with PowerShell

storing Credentials

Hey guys,

This post is mostly going to be me sharing an answer I wrote on StackOverflow, about a technique I use in my PowerShell modules on Github to safely store credentials, and things like REST Credentials.  This is something I’ve had on my blogging ‘To-Do’ list in OneNote for a while now, so it feels nice to get it written out.

I hope you like it, feel free to comment if you think I’m wrong!

The Original Question

I currently have a project in powershell which interacts with a REST API, and the first step after opening a new powershell session is to authenticate myself which creates a websession object which is then used for subsequent API calls. I was wondering what the best way of going about storing this token object across all Powershell sessions, because right now if I authenticate myself and then close & reopen powershell I need to re-authenticate which is rather inconvenient. I would like the ability to in theory authenticate once and then whenever I open up powershell be able to use my already saved websession object. At the moment I store this websession object in $MyInvocation.MyCommand.Module.PrivateData.Session
Original Question

My Take on Safely Storing objects on a machine with PowerShell

Since I’ve written a number of PowerShell Modules which interact with REST APIs on the web, I’ve had to tackle this problem before. The technique I liked to use involves storing the object within the user’s local credential store, as seen in my PSReddit PowerShell Module.

First, to export your password in an encrypted state. We need to do this using both the ConvertTo and ConvertFrom cmdlets.

Why both cmdlets?

ConvertTo-SecureString makes our plaintext into an Encrypted Object, but we can’t export that. We then use ConvertFrom-SecureString to turn the encrypted object back into encrypted text, which we can export.

I’m going to start with my very secure password of ham.

$password = "ham"
$password | ConvertTo-SecureString -AsPlainText -Force | 
  ConvertFrom-SecureString | Export-CliXML $Mypath\Export.ps1xml

At this point, I’ve got a file on disk which is encrypted. If someone logs on to the machine they can’t decrypt it, only I can. If someone copies it off of the machine, they still can’t decrypt it. Only me, only here.

How do we decrypt the text?

Now, assuming we want to get the same plain text back out to use late, we can add this to our PowerShell Profile, you can import your password like so.

$pass = Import-CliXML $Mypath\Export.ps1xml | ConvertTo-SecureString
Get-DecryptedValue -inputObj $pass -name password

$password 
>"ham"

This will create a variable called $password containing your password. The decryption depends on this function, so be sure it’s in your profile: Get-DecryptedValue.

Function Get-DecryptedValue{ param($inputObj,$name) $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($inputObj) $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr) New-Variable -Scope Global -Name $name -Value $result -PassThru -Force }

And that's it! If anyone knows who originally wrote the Get-DecryptedValue cmdlet, let me know in the comments and I'll give them full credit!

Enabling PowerShell Event Logging

Powershell logging

For one of my customers, we tried to enable PowerShell Module logging for ‘Over the shoulder’ event logging of all PowerShell commands.  We were doing this and enabling WinRM with HTTPs to help secure the company as we looked to extend the capabilities of PowerShell Remoting throughout the environment.  However, when we tried to enable the Group Policy Setting, it was missing in the GPMC!

In this post, we’ll walk through why you might want to do this, and what to do if you don’t see the settings for PowerShell Module Logging.

What is PowerShell Module logging?

PowerShell module logging allows you to specify which modules you’d like to log via a Group Policy or regkey, as seen in this wonderful write-up (PowerShell <3’s the blue team).

It allows us to get an ‘over-the-shoulder’ view, complete with variable expansion for every command a user runs in PowerShell.  It’s really awesome.  You can check the Event Log on a machine and see the results and all attempted PowerShell commands run by users.  If you then use SCOM or Splunk, you can snort these up and aggregate results from the whole environment and really track who is trying to do what across your environment.

PowerShell remoting

We loved it and wanted to turn it on, but when we opened the GPMC..

missin
Options should appear here under Computer \ Admin Template\Windows Components\Windows PowerShell

We were missing the options! Continue reading

SCCM 1606 Cloud Proxy Guide

Configmgr in the cloud

SCCM 1606 brings a cool new feature to us, allowing us to manage machines even if they aren’t in the office. We can push Windows updates, deploy software, and also configure devices using SCCM Client Settings and DCM, even if a machine is half-way across the world!

This feature is called the Cloud Proxy service 🔗, and in this step-by-step guide I’ll tell you why it’s cool and how to do it!

What problems does this solve?

One of the biggest challenges to the SCCM Admin in managing machines is handling those systems which rarely are in the office.

Some types of staff– such as our sales team –might cover a region and never bring their machine to the home office. If they don’t VPN either, and you don’t have DirectAccess set up, you might only see a machine once a year. Just a couple hours a week or month to push app updates ensure Antivirus is current and get those Windows updates installed. Very challenging.  You know what it’s like, for some users you just have to send an e-mail like this:

Please come to the office at some point this year, I’ll even buy donuts!

Cloud Proxy in SCCM tp1606 allows us to configure our environment to use Azure and its global footprint to extend the functionality of our management point, distribution point and even software update point to the Web. It’s like a freaking aircraft carrier for ConfigMgr, it extends our sphere of influence to cover the entire globe!

To the veterans out there, this might sound similar to a current feature however…

How is this different from IBCM though?

SCCM has offered a feature called Internet based client management for a while now.  It does cover some of the same ground as Cloud Proxy, however the key difference between the two is that with IBCM, we are taking ownership of all of the work of securing access to our SCCM Infrastructure from the outside Web.

That means adding new servers into a DMZ and all of that network change request and security compliance meetings (BARF) which goes with a big, scary change.  In IBCM, we’ll also have clients hitting our SCCM Infrastructure from over the Web so we also need to worry about our upload speed and take steps to ensure that serving content out doesn’t impact the quality of service for our internal users too.

Compare this to the solution offered by Cloud Proxy, in which we allow Azure and Microsoft to shoulder the burden for some of those tasks, and only have to worry about our SCCM server having a route available to Azure instead.

Azure is not a free meal

However there are Azure costs for running this.

In my test lab with a handful of machines with Azure Proxy, it cost about $2 a day to run, purely to keep the Azure Servers online.  Speaking entirely out of my butt, I wouldn’t expect the compute costs to be too high for managing machines, but I would factor in some fluff factor when presenting the costs to management, if you’re doing something vastly different than me, you might be spending more like $5 a day to keep the lights on the Azure Cloud Proxy Service.

Note: This is with two Azure hosts for redundancy, although you might decide to try to run with one host or maybe you need 10 depending on your risk tolerance.

You also will pay for data transfer out of Azure.  For the first 5 TB, the rate is $0.087 / GB, which is absurdly cheap.

To put this into perspective, let’s say you need to deploy Adobe Premier (it’s about 1 GB) to your entire remote marketing team, all 1000 of them (dear lord, can you imagine having to deal with 1,000 advertising primmadona’s?  So much plaid and skinny jeans…).

If they’re all remote, that’s about a terabyte of traffic, so it’d cost about $85 to deploy that one app.  That ain’t free but it’s a lot cheaper than the license for ANY app, and probably less than what the company would pay for one hour of your fully loaded cost to the employer🔗 .  Management will not care.

A more realistic scenario is Windows Updates or AV updates.  The average Forefront Definitions package is 250KB.  Three of those a day, 30 times a month is 24MB per system.  For those same thousand computers, it’d only be  24 GB, or $2 to ensure your machines always have up to date AV Definitions delivered by your company.

These are estimates for generic situations, so read up on pricing 🔗 before you decide to commit.

Continue reading

SCCM 1602 nightmare upgrade

This week, we had a scary ConfigMgr 1602 upgrade.

Of course, as a consultant you have to be cool like a fighter pilot in the face of adversity, as crying is frowned upon by customers when they see your hourly rate.  So when everything falls over, and there are spiders coming out of the air conditioner, you say ‘hmm, that’s strange’ and then whip out your laptop to begin opening log files like a fiend.

It was a day like any other

Before the upgrade, I ran through a practice run on my test lab domain, to try to prepare myself. We then used Kubisys to mirror our production SCCM and ran /TestDbUpgrade. All good.

However during the install we saw the install hang for a long time trying to stop sccm services.

Note :We saw this before with this same instance of SCCM when we upgraded to 1511; the install froze for an hour trying to stop the services. At that time, we manually stopped the SMS exec service and component Manger and the install proceeded.

So when the install froze again, we gave it ten minutes before manually stopping the SMS exec service. Install proceeded like normally and all looked fine in the logs until we tried to open the console.

ohno01
Configuration Manager cannot connect to the site

When I see errors like this, I immediately thing SMS Provider.

What’s the SMS Provider?
Good question!  While we tend to think SQL when we think SCCM, in reality ConfigMgr really stores a lot of information in the WMI repository on the Primary sites and the CAS.  Additionally, WMI plays a role in how data is stored in the SQL Database for ConfigMgr as well.

The SMS Provider is critical for allowing this interaction between the SCCM Console, WMI and SQL.  If you don’t have any working SMS Providers you can’t use the ConfigMgr console!

 

So we knew the SMS provider (which does a bunch of WMI stuff) likely couldn’t be reached, so I opened up the primary sites SMSProvider log \primary\SMS_SiteCode\logs\SMSProv.log and check out this nasty looking message! Continue reading

SCCM 1602 Query – All Online Machines

Quickpost: SCCM 1602 Query – All Online Machines

With the Advent of client activity indicators in SCCM 1606:

t01

We can now see which machines are online at a given time.  I love these green checkboxes.

I thought it would be cool to try to make a collection of only currently online machines.  So, into the query editor we go!  We’ll add a new query rule, and then use the wizard to add a new value.  This is all that you need to grab only the currently online systems.

t02

This collection works VERY well for Incremental Updates.  However, Scheduled Updates don’t make much sense

And the end result:

t03
They’re all online!  So green!