PowerShell Exception calling "Start" with "0" argument(s) from within another function - powershell

I am writing my first Powershell script and coming from C# am confused, my code is below:
function Run(
[string] $command,
[string] $args,
[Ref] [string] $stdout,
[Ref] [string] $stderr
)
{
$p1 = New-Object System.Diagnostics.Process
$p1.StartInfo = New-Object System.Diagnostics.ProcessStartInfo;
$p1.StartInfo.FileName = $command
$p1.StartInfo.Arguments = $arguments
$p1.StartInfo.CreateNoWindow = $true
$p1.StartInfo.RedirectStandardError = $true
$p1.StartInfo.RedirectStandardOutput = $true
$p1.StartInfo.UseShellExecute = $false
$p1.Start()
$p1.WaitForExit()
}
$p = New-Object System.Diagnostics.Process
$p.StartInfo = New-Object System.Diagnostics.ProcessStartInfo;
$p.StartInfo.FileName = "ping"
$p.StartInfo.Arguments = "142.553.22242.2"
$p.StartInfo.CreateNoWindow = $true
$p.StartInfo.RedirectStandardError = $true
$p.StartInfo.RedirectStandardOutput = $true
$p.StartInfo.UseShellExecute = $false
$p.Start()
$p.WaitForExit()
$code = $p.ExitCode
$stderr = $p.StandardError.ReadToEnd()
$stdout = $p.StandardOutput.ReadToEnd()
Run("ping","208.67.222.222","","")
The $p.Start() works, but for some reason the parameters passed in to the Run function are ignored and $p1 fails. What am I doing wrong please?
Exception calling "Start" with "0" argument(s): "The system cannot find the file specified"
At C:\Users\Administrator\Desktop\logtofile.ps1:27 char:5
+ $p1.Start()
+ ~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : Win32Exception
Exception calling "WaitForExit" with "0" argument(s): "No process is associated with this object."
At C:\Users\Administrator\Desktop\logtofile.ps1:28 char:5
+ $p1.WaitForExit()
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException

You have to call run as follows:
Run "ping","208.67.222.222","",""
putting in between the parentheses passes it to the function as a single array argument.

I wasn't trying to start a process from inside a function, but I was getting the same error. It took me a few minutes to realize that it was one of my favorite time-wasters: a UAC trap. I hadn't started PowerShell using "Run as administrator". You have to have admin privileges and run the code as such to start/stop/modify processes that you don't own and this error message is totally unhelpful in this regard.

function Demo {
param (
$fileName,$Arguments
)
$p = New-Object System.Diagnostics.Process
$p.StartInfo = New-Object System.Diagnostics.ProcessStartInfo
$p.StartInfo.FileName = $fileName
$p.StartInfo.RedirectStandardError = $true
$p.StartInfo.RedirectStandardOutput = $true
$p.StartInfo.UseShellExecute = $false
$p.StartInfo.Arguments = $Arguments
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode
}
Demo "getmac" " /v"

I got this error with the start() function on a service because a colleague set the service to "disabled" in the Windows Services window. Setting it back to "Manual" fixed it.

Related

This command is not available. By writing to Word with Powershell

My powershell script yesterday stopped working. I have changed nothing in the code or in the path to files. It just stopped working. I can't explain it.
I've tested all path and all variables and its look fine.
function Gen-Doc($Replace, $dataToRaplace, $user_name, $austauch) {
$objWord = New-Object -comobject Word.Application
$objWord.Visible = $false
if ($austauch -eq $true) {
$objDoc = $objWord.Documents.Open("C:\Path\To\Docu\Vorlage\Doc1.docx")
} else {
$objDoc = $objWord.Documents.Open("C:\Path\To\\Docu\Vorlage\Doc2.docx")
}
$objSelection = $objWord.Selection
$n = 0
while ($n -ne $dataToRaplace.Length) {
$FindText = $Replace[$n]
$ReplaceWith = $dataToRaplace[$n]
$MatchCase = $False
$MatchWholeWord = $true
$MatchWildcards = $False
$MatchSoundsLike = $False
$MatchAllWordForms = $False
$Forward = $True
$Wrap = $wdFindContinue
$Format = $False
$wdFindContinue = 1
$wdReplaceAll = 2
$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, `
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,`
$Wrap,$Format,$ReplaceWith,$wdReplaceAll)
$n++
}
$filename = $user_name
$objDoc.SaveAs("C:\Path\To\Docu\$filename.docx")
$objWord.Quit()
if ($checkbox2.Checked -eq $true) {
Start-Process -FilePath "C:\Path\To\Docu\$filename.docx" -Verb print
}
}
And here is error message
This command is not available.
At C:\Scripts\Done\Ausgabe.ps1:103 char:9
+ $a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWh ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
Make sure you don't have your document opened before doing $objDoc.SaveAs.
Check process manager for orphan WINWORD.EXE processes running.

Document.getElementsByTagName("span") problem with power shell version 2 windows 7

i,m write a a powershell script to open a web page by internet explorer and check the web page to find a link on the webpage by span tag and click on link to open a link but $IE.Document.getElementsByTagName("span") | ? {$_.InnerHTML -eq "$word" not working in windows 7 powershell version 2 , script is :
$IE = new-object -com internetexplorer.application
$req = [System.Net.WebRequest]::Create("http://device.com/link.html")
$resp = $req.GetResponse()
$reqstream = $resp.GetResponseStream()
$stream = new-object System.IO.StreamReader $reqstream
$go = $stream.ReadToEnd()
$IE.navigate($go)
$IE.visible=$true
start-sleep 10
$req = [System.Net.WebRequest]::Create("http://device.com/word.html")
$resp = $req.GetResponse()
$reqstream = $resp.GetResponseStream()
$stream = new-object System.IO.StreamReader $reqstream
$word = $stream.ReadToEnd()
write-host $word
$Link = $IE.Document.getElementsByTagName("span") | ? {$_.InnerHTML -eq "$word"}
$Link.click()
i want to replace any command to working this script with powershell version 2 in windows 7 and i don,t know what,s command can do that and find My mind link and click on that link with this script !
Hello My Friend #Theo
Script Change To This :
$IE = new-object -com internetexplorer.application
$req = [System.Net.WebRequest]::Create("http://device.com/link.html")
$resp = $req.GetResponse()
$reqstream = $resp.GetResponseStream()
$stream = new-object System.IO.StreamReader $reqstream
$go = $stream.ReadToEnd()
$IE.navigate($go)
$IE.visible=$true
start-sleep 10
$req = [System.Net.WebRequest]::Create("http://device.com/word.html")
$resp = $req.GetResponse()
$reqstream = $resp.GetResponseStream()
$stream = new-object System.IO.StreamReader $reqstream
$word = $stream.ReadToEnd()
write-host $word
$Link = #($IE.Document.getElementsByTagName("span") | ? {$_.InnerHTML -eq "$word"})[0]
$Link.click()
Not Working And Answer Is :
Cannot find an overload for "getElementsByTagName" and the argument count: "1".
At line:16 char:44
+ $Link = #($IE.Document.getElementsByTagName <<<< ("span") | ? {$_.InnerHTML -eq "$word"})[0]
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
You cannot call a method on a null-valued expression.
At line:17 char:12
+ $Link.click <<<< ()
+ CategoryInfo : InvalidOperation: (click:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

System.Printing.Addjob() Error in Powershell

So I am trying to create a script that will take a print job from one paused print queue and add it to an active queue. However I am trying to utilize the AddJob() function and upon calling it with or without parameters it returns an exception and I am not sure why. Here is what I have so far
$host.Runspace.ThreadOptions = "ReuseThread"
Add-Type -AssemblyName System.Printing
$permissions = [System.Printing.PrintSystemDesiredAccess]::AdministrateServer
$queueperms = [System.Printing.PrintSystemDesiredAccess]::AdministratePrinter
$server = new-object System.Printing.PrintServer -argumentList $permissions
$queues = $server.GetPrintQueues(#([System.Printing.EnumeratedPrintQueueTypes]::Shared))
foreach ($q in $queues) {
if ($q.IsPaused -eq 1)
{
$qPaused = new-object System.Printing.PrintQueue -argumentList $server,$q.Name,1,$queueperms
}
else
{
$qPlaying = new-object System.Printing.PrintQueue -ArgumentList $server,$q.Name,2,$queueperms
}
}
$byteContents = #('This is a test')
$byteContents | Out-File -FilePath "C:\testinput.txt"
[byte[]]$bytes = Get-Content -Encoding byte -Path "C:\testinput.txt"
#$printJob = $qPaused.GetJob(3).
$qPlaying.AddJob()
$jobStream = $printJob.JobStream
$jobStream | Out-GridView
#$jobStream.Write($bytes, 0, $bytes.Length)
#$jobStream.Close()
What this gives me is an error at the $qPlaying.AddJob() saying
Exception calling "AddJob" with "0" argument(s): "Specified argument was out of the range of valid values.
Parameter name: clientPrintSchemaVersion"
At line:23 char:1
+ $qPlaying.AddJob()
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
Thank you for any feedback.
The version of the Print Schema is defined when you call the constructor for the queue in this line:
$qPlaying = new-object System.Printing.PrintQueue -ArgumentList $server,$q.Name,2,$queueperms
You are using PrintQueue Constructor (PrintServer, String, Int32, PrintSystemDesiredAccess) where the Int32 is the Print Queue Schema version. The MSDN article has a remark that: "The Print Schema version released with Windows Vista is "1"." Which would make sense that when you use 2 and receive an out of range error that 2 isn't an acceptable value.
You could use 1 as the value or use an alternate constructor. For example:
$qPlaying = new-object System.Printing.PrintQueue -ArgumentList $server,$q.Name,$queueperms

Install windows update

I have following powershell script which should update my windows OS everytime I run it. Therefore I use the given windows API in order to search, download and install the updates. But somehow only searching for them actually works.
This is my script:
$global:scriptpath = $MyInvocation.MyCommand.Path
$global:dir = Split-Path $scriptpath
$global:logfile = "$dir\updatelog.txt"
write-host " Searching for updates..."
$session = New-Object -ComObject Microsoft.Update.Session
$searcher = $session.CreateUpdateSearcher()
$result = $searcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")
if ($result.Updates.Count -eq 0) {
Write-Host "No updates to install"
} else {
$result.Updates | Select Title
}
$downloads = New-Object -ComObject Microsoft.Update.UpdateColl
foreach ($update in $result){
try {
$update.AcceptEula()
$Null = $downloads.Add($update)
} catch {}
}
$count = $result.Updates.Count
write-host ""
write-host "There are $($count) updates available."
write-host ""
read-host "Press Enter to download\install updates"
$downloader = $session.CreateUpdateDownLoader()
$downloader.Updates = $downloads
$downloader.Download()
$installs = New-Object -ComObject Microsoft.Update.UpdateColl
foreach ($update in $result.Updates){
if ($update.IsDownloaded){
$installs.Add($update)
}
}
$installer = $session.CreateUpdateInstaller()
$installer.Updates = $installs
$installresult = $installer.Install()
$installresult
But I get following error:
Exception calling "Download" with "0" argument(s): "Exception from HRESULT: 0x80240024"
+ $downloader.Download()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
Somehow this line: $downloader.Updates = $downloads is not executed, but I don't know why. I also already tried running the script as an admin, didn't work either.
That error code is the WU_E_NO_UPDATE, described here. Basically it says that the Updates collection is not set or empty.

Silently handle errors in powershell

I am writing a troubleshooting script to determine which IP addresses in our Domain are accessible by WMI, and which are not. The script will read a list of input parameters (about 18,000 lines), and will output to a file the IP address and the username
IP address, Username
Problem is, when the WMI error is thrown, it writes to the file
IP address, Get-WmiObject : The RPC server is unavailable. .....numerous lines of error
I would like to make it such that when a WMI error it thrown, it writes the following
IP address, "WMI ERROR"
And here is the modified code for reference
#script_modified.ps1
$abc = $args
$startInfo = $NULL
$process = $NULL
$standardOut = $NULL
<#Previously created password file in C:\Script\cred.txt, read-host -assecurestring | convertfrom-securestring | out-file C:\Script\cred.txt#>
$password = get-content C:\Script\cred.txt | convertto-securestring
$a = Get-Content "C:\Script\test_input.txt"
foreach ($b in $a){
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = "powershell.exe"
$startInfo.Arguments = "C:\script\script2.ps1 " + $b
$startInfo.RedirectStandardOutput = $true
$startInfo.UseShellExecute = $false
$startInfo.CreateNoWindow = $false
$startInfo.Username = "service.infosec"
$startInfo.Domain = "Central"
$startInfo.Password = $password
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$process.Start() | Out-Null
$standardOut = $process.StandardOutput.ReadToEnd()
$process.WaitForExit()
# $standardOut should contain the results of "C:\script\script2.ps1"
Add-Content C:\script\list_of_computers_in_DOMAIN.log $b","$standardOut
}
EDIT
#Hyper Anthony
I updated my code to the following
try{
$process.StartInfo = $startInfo
}
catch{
$message = "WMI ERROR"
}
finally{
$process.WaitForExit()
Add-Content C:\script\list_of_computers_in_DOMAIN.log $b","$message
}
And I get following errors:
Exception calling "WaitForExit" with "0" argument(s): "No process is associated with this object."
At C:\script\script_modified.ps1:36 char:29
+ $process.WaitForExit <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
How to fix?
EDIT:
Below is the updated code:
foreach ($b in $a){
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = "powershell.exe"
...More Code...
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
try{
$process.Start() | Out-Null
$standardOut = $process.StandardOutput.ReadToEnd()
}
catch{
$standardOut = "WMI ERROR"
}
finally{
$process.WaitForExit()
Add-Content C:\script\list_of_computers_in_DOMAIN.log $b","$standardOut
}
}
There are no longer any errors that get output to the console, BUT, the output file is not as I wish.
When there is an WMI error, I would like the following line to be written
'sender-ip=10.10.10.10', WMI Error
But instead, the following is written
'sender-ip=10.10.10.10',Get-WmiObject : The RPC server is unavailable.
(Exception from HRESULT: 0x800706BA) ...many lines of error
or any other error may be printed instead of WMI Error.
Thanks once again!