PowerShell Clean up after yourself!

When working in an ISE by default the variables are persistent.  What this means is after your script has finished the variables are still held in memory and you can interrogate the values at the command line.  This can be really useful but there’s always two sides to everything.

The same thing happens with functions.

You MUST place functions at the top of a script.

If you put a line of code at the top of the script that calls a function that is declared several lines of code below then the call will never succeed, or will it?

In a production one time run it would never work because the function is not “loaded” yet.  When debugging a script in the ISE once you run your script the function can be called from the command line.  Again a really useful thing.

The downside is that when you then put your script into production it inexplicably fails.  It only works in the ISE because the variables and functions are persistent between the debug runs.  In production you hit the chicken and egg problem.

The long and the short of it is that you really should clean up inside your own script and make sure everything you create you remove at the end of the script and just to be doubly sure you can remove the variables before you instantiate them – we don’t really care if the chicken or the egg came first!

You can remove a variable like this

if ($DN) { try { Remove-Variable -Name DN -Scope Global -Force } catch { } }

Note we check if the variable exists first before trying to remove it. I use try and catch as well as the -ErrorAction options to try and suppress any errors this may generate to screen.

At the top of the script you set a variable $startupVariables .

# Store all the start up variables so you can clean up when the script finishes.
if ($startupvariables) { try {Remove-Variable -Name startupvariables  -Scope Global -ErrorAction SilentlyContinue } catch { } }
New-Variable -force -name startupVariables -value ( Get-Variable | ForEach-Object { $_.Name } ) 

At then at the end of the script I call a very simple function to remove any variables that didn’t exist before the script started. I’m using a belt and braces approach here to try and eliminate any possible errors with persistent variables. I’ll also usually add some debug switches so I can turn this behaviour on and off.

Function Clean-Memory {
Get-Variable |
 Where-Object { $startupVariables -notcontains $_.Name } |
 ForEach-Object {
  try { Remove-Variable -Name "$($_.Name)" -Force -Scope "global" -ErrorAction SilentlyContinue -WarningAction SilentlyContinue}
  catch { }
 }
}
Advertisements

4 thoughts on “PowerShell Clean up after yourself!

  1. […] PowerShell Clean up after yourself! (clan8blog.wordpress.com) […]

  2. scott b dragoo

    I know this is an old blog post (in ‘Internet years’), but I am “borrowing” your Clean-Memory function for some of my code.

  3. Love your script, btw, startupVariables uses different casing

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.