Link to home
Start Free TrialLog in
Avatar of JWeb Admin
JWeb Admin

asked on

Powershell variable - string

I have a Powershell function that successfully uninstalls VMware tools remotely.  If I try to pass in a value, the function stops working.  I believe this has something to do with perhaps the string literal not being passed in properly.

Here's the function and how I'm calling it.  If I change $Applications = @("VMware Tools") to something like $Applications = @($Application) and pass in $application, it doesn't work.  Is this related to the double quotes?  It is searching the list of installed apps for VMware Tools, and runs the uninstaller.

function Uninstall-VMApplication
{
    Param (        
		[Parameter(Position=0, Mandatory=$true)]
        $VM,

        [Parameter(Position=1, Mandatory=$true)]
        $Applications,

        [Parameter(Position=2, Mandatory=$true)]
        $Credential
    )
    Invoke-Command -ComputerName $VM.ComputerName -Credential $Credential -ScriptBlock {
        $package = @("VMware Tools")
            foreach($package in $Applications){
            $app = Get-WmiObject -Class Win32_Product | Where-Object {
            $_.Name -match "$Application"
            }
         $app.Uninstall()
        }
        Restart-Computer -ComputerName $VM -Force
    }
}

Uninstall-VMApplication -VM $VM -Applications $Applications -Credential $Credential

Open in new window


If I replace:

$package = @("VMware Tools")
with
$package = @($Applications)

The function fails because it cannot find "VMware Tools" installed.
Avatar of becraig
becraig
Flag of United States of America image

Why are you not just assigning the string value ?

$Applications = "VMware Tools"

instead of an array

Are you planning to have multiple values for the $Applications variable ?
Avatar of JWeb Admin
JWeb Admin

ASKER

Because I want to re-use the function for other projects, and I don't want to limit myself to just VMware Tools - I want to pass in a value or multiple values for $Applications.
I think you had some things mixed up, here is what I think you want to do

1) Create an array $Applications = @("app1", "app2", "app3")
2) loop thru this (foreach $package in $applications) {}
3) Run an uninstall of the app that matches package

function Uninstall-VMApplication
{
    Param (        
		[Parameter(Position=0, Mandatory=$true)]
        $VM,

        [Parameter(Position=1, Mandatory=$true)]
        $Applications,

        [Parameter(Position=2, Mandatory=$true)]
        $Credential
    )
    Invoke-Command -ComputerName $VM.ComputerName -Credential $Credential -ScriptBlock {
       $Applications = @("VMware Tools")
            foreach($package in $Applications){
            $app = Get-WmiObject -Class Win32_Product | Where-Object {
            $_.Name -match $package
            }
         $app.Uninstall()
        }
        Restart-Computer -ComputerName $VM -Force
    }
}

Uninstall-VMApplication -VM $VM -Applications $Applications -Credential $Credential

Open in new window

I'm setting up $Applications this way:

$Applications = "VMware Tools"

and then calling the function below that:

    Uninstall-VMApplication -VM $VM -Applications $Applications -Credential $Credential


I believe I am not creating the array correctly as you noted - so I should do this instead?

$Applications = @("app1")
Uninstall-VMApplication -VM $VM -Applications $Applications -Credential $Credential
ASKER CERTIFIED SOLUTION
Avatar of becraig
becraig
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Great - thank you!!!
When using Invoke-Command, if the scriptblock needs to use variables that are defined outside of the scriptblock (i.e. in the parent script, then you need to use the -ArgumentList parameter and modify your scriptblock to accept those arguments.  Here I'm using the same variable name inside and outside the scriptblock, but they don't have be the same.  The Params are matched based on position, not name, so if you're passing multiple arguments, the order is important.
Invoke-Command -ComputerName $VM.ComputerName -Credential $Credential -ScriptBlock {
       Param ($Applications)
            foreach($package in $Applications){
            $app = Get-WmiObject -Class Win32_Product | Where-Object {
            $_.Name -match $package
            }
         $app.Uninstall()
        }
        Restart-Computer -ComputerName $VM -Force
    } -ArgumentList $Applications

Open in new window