I want to create a script to remove a bunch of apps. I want to do this without user interaction once I've started the script.
This is the script I have so far; it doesn't work but hopefully you can see what I'm trying to do:
$App = Get-Content "C:\ListOFApps.txt" #get a list of apps
$args= '/quiet /norestart' # stores arguments for start-process
#gwmi gets the list of applications
# where selects just the apps im interested in removing
# start-process removes each app using msiexec with quiet and norestart options
gwmi win32_product | where { $App -contains $_.Name } | foreach {Start-Process 'msicexec /uninstall ' $_.IdentifyingNumber -ArgumentList $args -wait}'
This is the error that occurred:
ForEach-Object : Cannot process command because of one or more missing mandatory parameters: Process.
At C:\Users\username\AppData\Local\Temp\406f96a1-19b4-4e0d-af1b-b1ac2e32a6ba.ps1:3 char:62
+ gwmi win32_product| where { $App -contains $_.Name }| foreach <<<<
+ CategoryInfo : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
+ FullyQualifiedErrorId : MissingMandatoryParameter,Microsoft.PowerShell.Commands.ForEachObjectCommand
$_.IdentifyingNumber
Start-Process 'msicexec /uninstall $_.IdentifyingNumber' -ArgumentList $args -wait
You have an unbalanced single quote on the end of the line with the "foreach." I suspect fixing that is only the start of your problems. Good luck.
Also you have the Process misspelled. Should be "msiexec" not "msicexec"
Related
I have a question regarding how to properly structure a command with powershell.
Here is the code where I am having the issue.
$python_command =
{
param($script)
C:\Python27\python.exe $script
return $lastexitcode
}
$exit_code = Invoke-Command Copy-Item -Path C:\TestWare\jsonStuff.json -Destination
C:\Tunnel\Tunneling\jsonStuff.json -ToSession $Session - ScriptBlock $python_command -ArgumentList $exec_script
#Clean up
ExitWithCode($exit_code)
I'm assuming there there is an issue with how $exit_code is formatted because when it has this value
Copy-Item -Path C:\TestWare\jsonStuff.json -Destination C:\Tunnel\Tunneling\jsonStuff.json -ToSession $Session
there are no issues. I want the python command to run as well though. Can these commands be separated or how would they work as one? At the moment, I am getting the following error
Invoke-Command : A parameter cannot be found that matches parameter name 'Path'.
At C:\TestWare\run-test3.ps1:122 char:39
+ $exit_code = Invoke-Command Copy-Item -Path C:\TestWare\ ...
+ ~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
Any ideas on how to fix? I am on Powershell version 5 as well.
(EDIT) Here is my ExitWithCode function
function ExitWithCode
{
param
(
$exitcode
)
$host.SetShouldExit($exitcode)
exit
}
Invoke-Command has many different parameter sets, but just two fundamental ways to specify what command to invoke [remotely]:
via the -FilePath parameter, which expects a local script's path whose content is converted to a script block, which is then executed on the target machine.
via the -ScriptBlock parameter, which accepts a script block ({ ... })
Therefore, your attempt to pass a script block and a Copy-Item call directly cannot work.
It looks like you need 2 statements:
The Copy-Item call to copy something to session $Session with -ToSession.
The Invoke-Command statement to execute script block $python_command in session -Session $Session.
You could only get away with a single Invoke-Command call if you read the content of C:\TestWare\jsonStuff.json into memory and passed it as an argument to the script block and acted on that argument accordingly.
I am trying to individually monitor memory usage of a process (w3wp.exe) that has multiple instances of itself by filtering out a string found in the process' CommandLine property.
It works when I run this script locally:
$proc = (WmiObject Win32_Process -Filter "Name = 'w3wp.exe'" | Where-Object {$_.CommandLine -like "*SomeTextFromCl*"})
$id = $proc.ProcessId
$ws = [math]::round((Get-Process -Id $id).WS/1MB)
Write-Host $ws
However, when I try to run it remotely through Invoke-Command, I get an error telling that the Id property's value is null:
Cannot bind argument to parameter 'Id' because it is null.
+ CategoryInfo : InvalidData: (:) [Get-Process], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetProcessCommand
+ PSComputerName : RemoteServerName
My Invoke-Command syntax is:
Invoke-Command -ComputerName RemoteServerName -FilePath script.ps1 -Credential $mycredential
I'm sure it's simple but I'm back to PS after a long absence and I had a look around but couldn't find anything really helpful.
You are writing the answer to the console. You use the ps1 as a function, so you should use:
return $ws
instead of
write-host $ws
I want to start a background job and capture it's process id into a .pid file. I was able to do it with the Start-Process as follows:
Start-Process C:\process.bat -passthru | foreach { $_.Id } > start.pid
Now, I want to wrap Start-Process with Start-Job, to run it in the background, like this:
$command = "Start-Process C:\process.bat -passthru | foreach { $_.Id }"
$scriptblock = [Scriptblock]::Create($command)
Start-Job -ScriptBlock $scriptblock
Unfortunatelly, this doesn't work and Receive-Job gives me the following error:
The term '.Id' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (.Id:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : localhost
Looks like it's something wrong with the $_ variable. Maybe it gets overwritten by the Start-Job.
Any clues greatly welcome!
That is because the variable is being expanded when using double quotes. If you want to keep the $_, then you need to use single quotes.
$command = 'Start-Process C:\process.bat -passthru | foreach { $_.Id }'
$scriptblock = [Scriptblock]::Create($command)
Start-Job -ScriptBlock $scriptblock
I'm trying to execute the following two lines of code in PowerShell v2.0 as a job, and am having trouble. I think I have the syntax right, but I can't get it to do what I think it should do, so I clearly am doing something wrong...
$report = <command line thing>
invoke-expression $report
These two lines work in PowerShell. But when I try to put it into a start-job command:
start-job -scriptblock {invoke-expression $report} -argumentlist $report | wait-job | receive-job
I get the following error:
Cannot bind argument to parameter 'Command' because it is null.
+ CategoryInfo : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpre
ssionCommand
+ PSComputerName : localhost
I understand that error as saying that the argument I'm passing the invoke-expression is null, but, I'd thought that by passing $report in the -argumentlist param, it'd get through?
You cannot access $report directly unless you do:
-scriptblock {param($report) invoke-expression $report}
The param($report) part captures the $report variable passed in via -ArgumentList and makes it available for use inside the scriptblock.
I am currently writing a PowerShell script to stop a few processes, start a program, and then restart those processes. The problem arises when I feed the processes into an array variable to restart them later.
My code:
$direc = "C:\Program Files (x86)\PathTo\Program.exe";
$arguments = "/theseArguments1", "/theseArguments2";
$processesDefined = #();
$processes = "notepad", "explorer";
ForEach ($i in $processes)
{
$processesDefined += get-process -name $i | select-object path;
get-process -name $i | stop-process -force;
}
start-process -filepath $direc -ArgumentList $arguments -NoNewWindow -wait;
ForEach ($i in $processesDefined)
{
start-process -filepath $i;
}
When debugging the $processesDefined.Count displays 2 and the $processesDefined displays as expected yet when it gets to tjhe time to start the processes I get:
Start-Process : This command cannot be executed due to the error: The system ca
nnot find the file specified.
At D:\Desktop\Aion.ps1:17 char:18
+ start-process <<<< -FilePath $i;
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOp
erationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.C
ommands.StartProcessCommand
I've done a lot of searching but can't find anything of real help. Any help with this would be greatly appreciated. Thank you.
Output of $processesDefined:
[DBG]: PS D:\Desktop>>> $processesDefined
Path
----
C:\Program Files\Windows Media Player\wmpnetwk.exe
C:\Windows\explorer.exe
_____________________________________________________________
Try doing it this way. The way you are doing it leaves the variable $processesDefined with a table heading (PATH) and this will screw things up.
$processesDefined += (get-process -name $i).Path
This way will just give you the path with no table heading