Search code examples
powershellvariablesinstance-variables

Powershell is reanimating variables in Scripts


Good evening

I have this Problem with this Version

PS C:\temp> $PSVersionTable.PSVersion.Major
4

This is a really strange problem... despite of initialized variables, PowerShell script is somehow able to reuse variable values from previous invocations.

The script is simple; to show the problem, I work with a list of virtual machines:

  1. Read all Virtual Machines into an Array
  2. Select the 1st Element in the Array
  3. Add a new Property to the Object from step 2
  4. The Problem: if I run the script a second time, the new Property is already there - despite all Variables are initialized. If I start the Script in a new session, the new Property is missing on the 1st run, afterwards it is already there.

Here is the simple Code:

Set-StrictMode -Version 2.0
# Read all Virtual Machines into an Array
$AllVMs = @()
$AllVMs = Get-VM

# Get the 1st Virtual Machine
$VM = $null
$VM = $AllVMs[0]

# Prepare my Property
$MyList = @()
$MyList += "Test"

# If the Property already exists, just add my List
if ($VM.PSobject.Properties.Name -match "MyList") {
  $VM.MyList += $MyList
} else {
  # My Property does not exist: create it
  $VM | Add-Member –MemberType NoteProperty –Name MyList –Value ($MyList)
}

# Give Back my VM Object
$VM

To test the script, I just count the number of MyList-Elements:

PS C:\temp> $result = c:\temp\testvar.ps1
PS C:\temp> $result.MyList.Count
1
PS C:\temp> $result = c:\temp\testvar.ps1
PS C:\temp> $result.MyList.Count
2
…

Does somone can help me with this Problem?

Thanks a lot for any help!!

Kind regards, Tom


Solution

  • I have asked this question to 'the scripting guy' Forum, too.

    I've got two great answers:

    1. From jrv:
      You are not exiting from PowerShell. The VM object is dynamic to the session. It persists until you close PowerShell. Some objects are like this. The code base drags them I to PowerShell and they remain cached. I suspect this is what is happening here.

    2. From Evgenij Smirnov:
      Hi,
      this appears to be specific to the VM object. If I substitute Get-VM by Get-Process or Get-ChildItem c:\ I do not experience this behaviour. If I select a new VM every time I run the script, it does not retain the property. On the other hand, if I do (Get-VM)[0].MyList after running the script four times, I get four entries.
      So this persistence is obviously built into the Hyper-V module, the custom property getting added to the instance of the VM object itself. So you could initialize MyTest to empty on the whole VM collection like this:

    $AllVMs | foreach {
      if ($_.PSobject.Properties.Name -match "MyList") {
        $_.MyList = @()
      }     
    } 
    

    Kind regards, Tom