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.
If I replace:
$package = @("VMware Tools")
with
$package = @($Applications)
The function fails because it cannot find "VMware Tools" installed.
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
If I replace:
$package = @("VMware Tools")
with
$package = @($Applications)
The function fails because it cannot find "VMware Tools" installed.
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
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
ASKER
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
$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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
$Applications = "VMware Tools"
instead of an array
Are you planning to have multiple values for the $Applications variable ?