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
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.
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
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
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.
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!