Friday Fun: Create All PowerShell Profile Scripts

talkbubbleWhenever I train on PowerShell I inevitably get around to discussing PowerShell profile scripts. For those of you new to PowerShell, a profile script is where you put all the commands you want to run that will define your PowerShell session just the way you need it. You might load some snapins, create some PSDrives or define some variables. There are actually several profile scripts that can be run, depending on whether you are in the PowerShell console, the PowerShell ISE or some other PowerShell host.

The profile paths are hard-coded. You can see all of them by looking at the built-in $profile variable.

You can also look at just $profile which will show you the script for the current user on the current host. If you look at this in the ISE you’ll see some things are different.

ISE-Profiles

This variable is a bit tricky. Even though you can see properties here, if you pipe $profile to Get-Member all you get is a string definition. Here’s another way you can discover these.

Although I don’t really care about the length so let’s filter it out.

Now for the fun part. That value is a path so I can use Test-Path to see if it exists. If not, I can create the profile and at least indicate that is isn’t being used. Because most of these files don’t exist by default and in fact the WindowsPowerShell folder doesn’t exist under Documents until you create it, you might have to create the parent folder first. So I came up with a little script called Create-AllProfiles.ps1.

The script takes advantage of a feature in PowerShell 3 that will automatically enumerate properties. In PowerShell 2.0 I would need to do this:

But now in v3 and later I can do this:

The value property would show all of the values, including the length so because I’m getting an array, I can use a range of index numbers to select just the ones I want. In my script each value is tested and those that don’t exist are passed on to Foreach-Object.

For each path, I first split it so I can test if the parent path exists. If not, it is created. Then I create some text that will be inserted into each new profile script. The script supports -WhatIf so you can see what it would do before you run it for real.

create-allprofiles

I end up with a profile script that looks like this:

create-allprofiles-2

Ideally, I would recommend you digitally sign the profile scripts, assuming you are using an AllSigned execution policy, so that no changes can be made to these scripts without your knowledge. Just don’t forget to run this in the PowerShell ISE as well. If you have profiles already created, they will be ignored. And should you decide later to take advantage of any of the profile scripts, they are ready for you to edit.

Learn, enjoy and have a great weekend.

More Fun with String Properties

The other day I posted an article about converting string properties that you might get from running a command line tool into a PowerShell named property. I was continuing to experiment with it. Here’s some code on how I could use it.

I end up with output like this:

It would be nice to clean up the values and remove non word characters like the “<”. But I wouldn’t want to remove the period from the image property. So I came up with this:

Each data element is cleaned up using the Replace operator to replace any character in the regular expression pattern with nothing. Then I started experimenting with command line output that display as a series of lines like ipconfig /displaydns. First, I have to decide what to process so I want to get all lines that have ‘. . .’ in it.

Looking at the output I can see that basically I get an “object” for every group of 5 lines.

This code counts in groups of 5 and gets each group of elements using a range of index numbers. Each line in the range is then split into 2 strings on the first : character. The first item will be the property name which is converted into a string property and the second item will be the data. This gives me a custom object:

Which lead to the next challenge. The last line is being interpreted as two separate properties which is a bit of a mess. So I need a way to rename that line. Or actually any line. Maybe instead of TimeToLive I want to use TTL. Here’s the next step.

I have to know in advance what line number each property will be on. But since I do I’ll create a hashtable that uses the line number (starting at 0) as the key. The hashtable value will be the replacement property name. In my process scriptblock I’m keeping track of how many lines I’ve worked on. If the counter matches a key in the hashtable I do a replacement. Now I get this:

At this point I recognize that I have another repeatable code that I could turn this into a function.

This function relies on Convert-StringProperty. At some point I should package this and few other things I have into a module. But for now you’ll have to make sure the other function is loaded into your shell. The default processing assumes you have tabular output like you get from arp -a. You can specify input that is in a list but then you also need to specify how many lines are grouped together. You can also specify a hashtable of replacement property names for either input type. To keep things easier, the hashtable keys start counting at 1.

You can’t pipe into the command. You have to specify the input like this:

convert-clioutput-1

Here are some other examples using tabular output including a property rename.

convert-clioutput-2

Using my IPCONFIG example from earlier, here’s I can do it with my new function.

In the grid view I can further filter or sort.

convert-clioutput-3

One remaining issue here is that everything is a string. But in that regard it really isn’t that much different than when you import a CSV file. I guess this gives me something else to work on. In the meantime, try this out and let me know what you think.

Convert a String to a PowerShell Property Name

talkbubbleOver the last few years I’ve written and presented a bit on the idea of turning command line tools into PowerShell tools. We have a lot of great CLI based tools that are still worth using. What I’ve done is come up with tools and techniques for turning their output into an object that can be used in the PowerShell pipeline. Often all I need to do is parse and clean up command line output. But one thing that has always nagged me is what to use for property names.

For example, I can pretty easily turn output from the ARP.EXE command into objects. Here’s what I start with.
arp-a

What I want to do is take the column headings and turn them into properties. The problem is I don’t like spaces in property names. Plus, I would need to know in advance the command line heading so I could use something like a custom hashtable to rename. I was after something a bit more convenient and something that would work with almost any command line output, although I think tabular output works best. Thus I came up with a short function I call Convert-StringProperty.

Here’s how it works. I’ll take the raw ARP output and skip the first couple of lines.

The $raw variable has the data I want to turn into objects.

The first line contains the property names but I want them without the spaces. As a separate step, outside of the function, I need to split the first line. I’m going to do that with a regular expression pattern that matches 2 or more white spaces.

I can take the first line, item [0], remove leading and trailing spaces and split it. This will give me three strings: Internet Address, Physical Address, and Type. Each of these is then piped to my Convert-StringProperty.

The function will look at each string and split it again based on a delimiter, which by default is a space. But you can specify something different if you run into CLI names like INTERNET_ADDRESS. Each word is then processed with a capital first letter. The end result is camel case so “Internet Address” becomes “InternetAddress”.

Once I know what my property names will be, I can continue parsing the command line output and create a custom object.

You still need to come up with code to process your command line tool, but you can use this function to define proper PowerShell properties. Here’s one more example.

This takes command output like this:

And turns it into PowerShell output like this:

In another article I’ll share with you another tool that takes advantage of this function. Enjoy.

Advice, solutions, tips and more for the lonely Windows administrator with too much to do and not enough time.

%d bloggers like this: