Clean Up Your PowerShell Environment by Tracking Variable Use

Clean Up Your PowerShell Environment by Tracking Variable Use

  • Comments 2
  • Likes

Summary: Guest Blogger Ingo Karstein shares a Windows PowerShell function to track and remove variables from your environment.

 

Microsoft Scripting Guy Ed Wilson here. Today, we have a guest blog article written by Ingo Karstein. He has a really clever way to clean up your Windows PowerShell environment. I will let Ingo tell you a bit about himself.

 

This is Ingo Karstein. I’m a senior consultant for SharePoint, Windows PowerShell, and custom development. For about the last year, I have written a blog (http://ikarstein.wordpress.com) where I discuss problems, ideas, and solutions related to these topics. 

Today I want to show you how to clean up variables in Windows PowerShell. Let’s say you are an administrator in an organization and you have written a Windows PowerShell profile that is loaded on every Windows PowerShell session startup. This profile is used for every user that may start Windows PowerShell. In this script you may do lot of stuff: read SharePoint lists, manipulate Active Directory Domain Services, read WMI, and trace the Event log. You have used dozens of Windows PowerShell variables.

Finally, you may want to clean up your profile script so that users cannot access the profile script data stored in these variables. Variables in Windows PowerShell are objects provided by the Windows PowerShell provider:

PS> get-psprovider

Name               Capabilities                                Drives

WSMan             Credentials                                {WSMan}

Alias                  ShouldProcess                           {Alias}

Environment      ShouldProcess                           {Env}

FileSystem         Filter, ShouldProcess                   {C, Z, G}

Function            ShouldProcess                           {Function}

Registry             ShouldProcess, Transactions        {HKLM, HKCU}

Variable                        ShouldProcess                           {Variable}

Certificate          ShouldProcess                           {cert}

 

Windows PowerShell providers are interfaces that connect hierarchical storage to Windows PowerShell, such as file system, Windows registry, Active Directory Domain Services, and Windows certificate store. The storage types have container objects such as folders in the file system and leaf objects such as files in the file system.

There are some “flat” storages connected to Windows PowerShell with Windows PowerShell providers: Variable, Function, Environment, and Alias. These storages do not have containers, only leafs.

The Variable Windows PowerShell provider represents the variables used in the windows PowerShell session. Let’s try it:

PS> get-item Variable:*

 

Name                                       Value

null

false                                          False

true                                          True

MaximumErrorCount                  256

MaximumVariableCount             4096

MaximumFunctionCount 4096

MaximumAliasCount                   4096

MaximumDriveCount                  4096

Error                                         {}

PWD                                         C:\Users\User2

?                                               True

MaximumHistoryCount               64

 

You can see a list of objects. These objects have at least two properties: Name and Value. Name is the name of the variable. Value is its value. But there are more properties (you can see here that I use a German localized Windows PowerShell session):

PS> get-item variable:PSCulture | fl

 

 

PSPath        : Microsoft.PowerShell.Core\Variable::PSCulture

PSDrive       : Variable

PSProvider    : Microsoft.PowerShell.Core\Variable

PSIsContainer : False

Value         : de-DE

Name          : PSCulture

Description   : Die Kultur der aktuellen Windows PowerShell-Sitzung.

Visibility    : Public

Module        :

ModuleName    :

Options       : ReadOnly, AllScope

Attributes    : {}

 

If you try the Get-Member cmdlet, you’ll figure out that the type of such a variable object is System.Management.Automation.PSCultureVariable.

PS> get-item variable:PSCulture | gm

 

You can use the Variable Windows PowerShell provider as you would any other provider, such as the file system provider. You can add new items to the variable storage:

PS> New-Item -Path "variable:My New Variable" -Value "Hey, Scripting Guy!"

 

Name                           Value

My New Variable           Hey, Scripting Guy!

 

You can check for their existence:

PS C:\Users\User2> test-path -Path "variable:My New Variable"

True

 

You can get their value (remember, it’s an object that you get with Get-Item):

PS> (get-item -Path "variable:My New Variable").Value

Hey, Scripting Guy!

 

Of course, you can access them the “common way”:

PS C:\Users\User2> ${My New Variable}

Hey, Scripting Guy!

 

(You need to use braces because the name of the variable contains spaces.)

Do you know that you can delete variables in Windows PowerShell? Yes, you can remove them:

PS C:\Users\User2> remove-item -Path "variable:My New Variable"

 

After that, the variable does not exist anymore!

PS C:\Users\User2> test-path -Path "variable:My New Variable"

False

 

In this way, you can manipulate every Windows PowerShell variable, as well as the variables created “normally”:

PS C:\Users\User2> $thatsMe = "Ingo"

PS C:\Users\User2> get-item variable:thatsMe

 

Name               Value

thatsMe             Ingo

 

Let’s return to the scenario of the beginning of this article: you want to clean up your Windows PowerShell session. Now you can create a script that acts in this way:

  1. At start of the profile script, read and store all variable names that exist.
  2. Execute the script.
  3. Remove all variables that did not exist at the script’s start time.

Here it is:

# All variables that exists at this moment will also exist

# after executing "Cleanup-Variables"

 

###################################################################

# stores all existing variable names in the variable

# "startupVariables". This variable itself will be

# removed too.

 

$startupVariables=""

new-variable -force -name startupVariables -value ( Get-Variable |

   % { $_.Name } )

 

function Cleanup-Variables {

  Get-Variable |

    Where-Object { $startupVariables -notcontains $_.Name } |

    % { Remove-Variable -Name "$($_.Name)" -Force -Scope "global" }

}

 

####################################################################

# Place your profile scripts in here

 

#Sample: -->

$myVariable = (Get-Process | select -first 5)

 

write-host "Here the variable exists"

$myVariable

#<--

 

 

####################################################################

# Now all variables created since execution of line 8 will

# be removed.

 

Cleanup-Variables

 

####################################################################

 

#Sample: -->

write-host "Now the variable is unknown"

$myVariable

#<--

 

There are more cmdlets specific to Windows PowerShell variables:

PS C:\Users\User2> get-command -noun variable

 

CommandType              Name                           Definition

Cmdlet                          Clear-Variable               Clear-Variable [-Name] <Stri...

Cmdlet                          Get-Variable                  Get-Variable [[-Name] <Strin...

Cmdlet                          New-Variable                New-Variable [-Name] <String...

Cmdlet                          Remove-Variable           Remove-Variable [-Name] <Str...

Cmdlet                          Set-Variable                  Set-Variable [-Name] <String...

 

Thank you for your attention.

 

Thank you, Ingo, for taking the time to share your function with us today.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi Ingo,

    this is quite the same approach I used in some scripts to get rid of unused variables :-)

    But ... for whatever reason ... I never came up with the idea to do so in my startup script which might be really useful!

    Thanks for pointing that out and explaining the variable provider in more detail!

    It is frequently overlooked for sure.

    Klaus.

  • Very helpfull. Thanks very much for posting!