Uninstall program from Remote Computer - powershell

I'd like to uninstall a program from a remote computer. I know the location of the MSI that was used for the install, it's on the remote server and the path can be seen in the variable $MSIPathFile below.
When I run the following script:
$TargetServer = "d-vasbiz01"
$MSIPathFile = "c:\biztalkdeployment\x.Int.MIS-3.0.0.msi"
Invoke-Command -Computer $TargetServer -ScriptBlock {Param($MSIPathFile, $UninstallFlag, $QuietFlag) Start-Process msiexec.exe "/x" $MSIPathFile "/qn"} -ArgumentList "$MSIPathFile", "/x", "/qn"
I get the following error:
Invoke-Command -Computer $TargetServer -ScriptBlock {Param($MSIPathFile, $UninstallFlag, $QuietFlag) Start-Process msiexec.exe "/x" $MSIPathFile "/qn"} -ArgumentList "$MSIPathFile", "/x", "/qn"
A positional parameter cannot be found that accepts argument 'c:\biztalkdeployment\x.Int.MIS-3.0.0.msi'.
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
Can anyone please advise what I'm doing wrong?

This is not really an answer to my question but it solves my problem of remotely uninstalling an MSI. I hope this can help someone else as I've spent the last 3 hours trying various techniques!
It turns out this can be achieved with a single line of code!
(Get-WmiObject -Class Win32_Product -Filter "Name='x.Int.MIS for BizTalk 2010 3.0.0'" -ComputerName $TargetServer ).Uninstall()
Courtesy of the following technet page: http://technet.microsoft.com/en-us/library/dd347651.aspx

Sorry for the late edit by pc crashed as I was replying so it half updated.
The problem is that the start Start-Process does not seem to expand the variable and execute it with the command. So what I do to get it to work is build up a string containing path to the executable and then another to parameters I would like to use. I then use the Invoke-expression command to execute it .
Here is an example below if you like I can edit your code ,but I thought you might like an example and explanation.
$MSIPathFile = "c:\biztalkdeployment\x.Int.MIS-3.0.0.msi"
$msiexec = "C:\Windows\System32\msiexec.exe"
$arguments = '/x' + $MSIPathFile + " /qn"
Invoke-Expression -Command "$msiexec $arguments"

Related

invoke-command with a parameter accessing UNC

I am trying to generate some IDs using a adobe tool called adobe-licensing-toolkit.exe.
I need to run the command remotely in 100 computers.
Executing the command manually works flawless
C:\temp\adobe-licensing-toolkit.exe -c -f \\XXXXXXX\c$\temp\IDs.csv
Adobe Licensing Toolkit (1.1.0.98)
Operation Successfully Completed
Now I tried to replicate that using remote PS without success. I think it is a matter of parameters.
The following command ends correctly but it generates the file locally in the remote computer.
Invoke-Command -ComputerName $comp -ScriptBlock { param($whatToDo,$targetCSV) &('C:\TEMP\adobe-licensing-toolkit.exe') --$whatToDo --$targetCSV "C:\temp\ID.csv"} -ArgumentList "generateChallengeKey","filepath"
If I try to use the UNC in the parameter, the result is Operation failed.
Invoke-Command -ComputerName $comp -ScriptBlock { param($whatToDo,$targetCSV) &('\\XXXXXXXX\c$\TEMP\adobe-licensing-toolkit.exe') --$whatToDo --$targetCSV "C:\temp\ID.csv"} -ArgumentList "generateChallengeKey","filepath"
I also tried to add path in the parameter. In that case is powershell who complains.
Invoke-Command -Session $Server01 -ScriptBlock { param($whatToDo,$targetCSV) &('C:\TEMP\FRL\adobe-licensing-toolkit.exe') --$whatToDo --$targetCSV } -ArgumentList #("generateChallengeKey","filepath \\XXXXXXX\c$\temp\ID.csv")
unknown option -- filepath \\XXXXX\c$\temp\ID.csv
+ CategoryInfo : NotSpecified: (unknown option ...c$\temp\ID.csv:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : XXXXXXX
I have the feeling that the issue is in the way parameter is passed but I haven't managed to find the solution.
The exe file is already present in all target computers.
Any suggestion?
Thanks
I would presume you have toolkit present in all remote computer in path: "C:\TEMP\adobe-licensing-toolkit.exe". You can simply use
Invoke-Command -ComputerName $comp -ScriptBlock { & "C:\TEMP\adobe-licensing-toolkit.exe" -c -f \\XXXXX\$env:Computername-IDs.csv}
Adding $env:Computername in share path would generate unique file for each computer.

Run Remote PS script to deploy software

I am trying to run a powershell script to deploy an MS Access solution to multiple desktops. I have my script on a server share and I have tried to run it with out success. I have used the invoke-command to try and run the script and get this error message
Access is denied
+ CategoryInfo : OperationStopped: (:) [], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException
+ PSComputerName : TESTVM-PC
I have also run all the psremoting commands and also tried the "Multi-hop" command. All with no success.
I have also tried to run the actual code in the script and it does not work.
Invoke-Command -Computer Dpierson-pc -Credential (get-credential) -ScriptBlock {
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force -Verbose
Copy-Item "\\Some\Bogus\Place\Access\*" C:\ -Recurse -Force -Verbose
Start-Process -FilePath "C:\Setup.exe" -PassThru -Verbose
Start-Sleep 30
Stop-Process -name Ninite -Force -Verbose
}
All I get is that the file setup could not be run because it does not exist. and the process then of course cannot be stopped as it does not exist. The credentials are my own and I am a domain admin. Any help would be appreciated. I have thought of making it batch file that I run via a group policy but that is the last thing I want to try as I plan on having more of these in the future.
P.S. I ran the " Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force -Verbose" on the machine locally as well.

How to Install Windows Updates on Remote Computer with PowerShell

I'm trying to install Windows Updates on a Remote Computer with this command:
$InstallSplat = #{
AcceptAll = $true
SendReport = $true
IgnoreReboot = if ($Reboot) { $false } else { $true }
PSWUSettings = #{
SmtpServer = "my mail server"
From = "myfrom <myfrom#myfrom.com>"
To = "myto <myto#myto.com>"
Port = 25
}
}
Invoke-Command -ComputerName $_ -Credential $cred -AsJob -ArgumentList $InstallSplat -ScriptBlock {
param([hashtable]$InstallSplat)
Import-Module PSWindowsUpdate
Install-WindowsUpdate #InstallSplat
$Error | out-file C:\install\installwinupdate.log -Append
}
I pass a credential Object with domain admin privileges in $cred but I still always get this error
Install-WindowsUpdate : Access denied (Ausnahme von HRESULT: 0x80070005 (E_ACCESSDENIED)) In Zeile:4 Zeichen:25
+ Install-WindowsUpdate #InstallSplat
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WindowsUpdate], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,PSWindowsUpdate.GetWindowsUpdate
The Command Install-WindowsUpdate itself does not have a credential parameter I could use. The Command needs to run in an elevated PowerShell, but I use an elevated PowerShell when starting this command on my Computer.
I Also tried creating a New-PSSession with my $cred and run Invoke-Command -Session $session instead of Invoke-Command -ComputerName $_ with the same result.
Does anybody know what's happening here? Why do I get Access denied?
It can't have anything to do with passing the $InstallSplat because the same thing happens if I don't pass any parameter at all and write the parameters and their Values directly at the command instead of splatting.
The Problem was, that you can't Download or Install Updates on a machine from another remote machine. Here's a list what you can or can't do remotely when it comes to Windows Updates
The solution is, to create a scheduled task on each server you want to install updates from a remote script, and start that task.
luckily, when you use the PSWindowsUpdate module, you don't have to do that yourself, you can just use Invoke-WUJob (formerly Invoke-WUInstall) which does the trick for you.
I used it like so ($ServerData.Value contains a list of my Servers) and it works like a charm. It creates a scheduled task on each server, and runs them immediately, if you add the -RunNow Parameter.
invoke-WUJob -ComputerName $ServerData.Value -Script { Import-Module PSWindowsUpdate ; Install-WindowsUpdate -AcceptAll -SendReport -IgnoreReboot -PSWUSettings #{From='xy';Port=25;SmtpServer='xy';To='xy'} | Out-File C:\install\PSWindowsUpdateLog.txt -Append} -Confirm:$false -verbose -RunNow
Note that what you specify as a script block in -Script will be pasted to -Command " <here> " in your scheduled task, so you should work with ' inside -Script.

Import-module: Could not find a part of the path

I am trying to connect to Exchange Online using PowerShell (As per this documentation) to add distribution group members.
However I am getting the following error:
Import-Module : Could not find a part of the path
'C:\Users\[my user account]\AppData\Local\Temp\tmp_hhw3s30w.xwu\tmp_hhw3s30w.xwu.format.ps1xml'.
At line:3 char:17
+ ... Import-Module -Name $name -Alias * -Function * -Prefix $p ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:String) [Import-Module], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand
My code is as follows:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $adCreds -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking -AllowClobber
Connect-MsolService -Credential $adCreds
My code has worked in the past on my machine, so I am struggling to work out why it is failing now.
Any help would be massively appreciated.
Another thing to try is closing and reopening PowerShell.
For me, I had deleted everything in my local temp folder earlier in the session. It seems PowerShell was using some of what was deleted.
When I reopened PowerShell, it apparently recreated the temp files/directories it needed, and Import-Module worked again.
I know this is an old thread but I had the same issue today. The way I fixed it was to update the module that imports modules, PowerShellGet
To check your current module version, enter: Get-Module -Name PowerShellGet
If you're still on version 1.x.x.x, update it with: Install-Module -Name PowerShellGet -Force -AllowClobber
You may need to close and reopen PowerShell. Be sure to check the version again and compare it with what's available at https://www.powershellgallery.com/packages/PowerShellGet/2.2.5

How to execute the below command in the powershell in a single line from server to the remote client

msiexec /i "example.msi" /q UserName="my username" password="my password"
The above command is executed perfectly in the command line but I need to execute in the powershell in a single line.
So any one please suggest.
I am new to the powershell.
I have tried below one:
Start-Process -FilePath msiexec -ArgumentList / /i, example.msi, "UserName='my username'","password='my password" -Wait
but it shows some issue:
Start-Process : A positional parameter cannot be found that accepts argument 'System.Object[]'.
At line:1 char:1
+ Start-Process -FilePath msiexec -ArgumentList / /i, "'example.msi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Start-Process], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
You've nearly got it, try this:
start msiexec -ArgumentList
"/i example.msi /q UserName=""my username"" password=""my password"""
If any of your arguments need quotes, you need to double them up.
Try using the "Invoke-Command" cmdlet. Should look something like this:
$computerlist = get-content c:\temp\ComputerNames.txt
foreach ($computer in $computerlist) {
Invoke-Command -ComputerName $computer -ScriptBlock {msiexec /i "\\servername\pathToFile\example.msi" /q UserName="my username" password="my password"}
}
Try looking at the help for this command.
In general when you see parameters such as arguments or argumentslist always keep in mind that an array is expected. Same for the `& path args' format.
The cool thing about the array is that each item will be offered to the executable as if it was implicitly quoted, similar to you surrounding with quotes a parameter in command prompt that contains a space.
For this reason I always use structures like
$arguments=#($var1,$var2)
Like this I never have to worry about what is in the variables. When creating the array in multi line and depending on each case it also makes easier the change management because adding a parameter is a line change. It also helps with commenting one out when troubleshooting
For example
$arguments=#(
$var1
$injectedVar
#$disabled
$var2
)