Open Serial Port with variable - powershell

I want to open a COM port in my powershell script:
function openComPort($number, $baud) {
$port = New-Object System.IO.Ports.SerialPort("COM$number", $baud, "None", 8, "One")
$port.Open()
return $port
}
$myOpenedPort = openComPort(1, 9600)
This fails with
New-Object : Exception calling ".ctor" with "5" argument(s): "Positive number required.
Parameter name: BaudRate"
At line:9 char:20
+ $port = New-Object <<<< System.IO.Ports.SerialPort("COM$number", $baud, "None", 8, "One")
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
You cannot call a method on a null-valued expression.
At line:11 char:12
+ $port.Open <<<< ()
+ CategoryInfo : InvalidOperation: (Open:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
What am I doing wrong?

You're calling your function wrong, Powershell (unlike other languages) doesn't require brackets when calling a function, see about_functions for further info.
Using them like that groups everything inside the brackets into a single item, this is being sent to the first parameter $number, leaving $baud empty - which is causing your errors.
The correct syntax is:
openComPort 1 9600
EDIT: It's also good practice to have your params into a param() block (this is a step towards using advanced functions.
And to also set a param type to ensure you receive the correct input type. They are both int in this case - as you only want a positive whole number.
This would update your function to:
function openComPort {
Param(
[int]$number,
[int]$baud
)
$port = New-Object System.IO.Ports.SerialPort("COM$number", $baud, 'None', 8, 'One')
$port.Open()
return $port
}
$myOpenedPort = openComPort -number 1 -baud 9600

Related

runspace: EndInvoke() fails to return all the scriptblocks output , only the last exception

The script block
$sb = {
write-output "Testing 1"
write-output "Testing 2"
throw " Exception in sb"
}
Calling EndInvoke() only returns the below. My runspace tasks are in some case hours long. I can not lose all the output except the last exception. I do not have control over the script blocks as they get passed into my cmdlets.
How do I resolve that?
Exception calling "EndInvoke" with "1" argument(s): " Exception in sb"
At line:1 char:1
+ $j.PowerShell.EndInvoke($j.Job)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : RuntimeException
By the time you call EndInvoke(), you are already too late. There is no way to receive the data from the output stream as all that data is discarded and the only thing you will get is the thrown exception message. Instead, you have to change how you do your initial BeginInvoke() call to allow you to capture the output.
Using an overloaded BeginInvoke(TInput,TOutput) call, you can both pass your input commands (if needed, or blank), as well as you have to supply a buffer for the output to be stored (of type System.Management.Automation.PSDataCollection[psobject]). So your code looks like this:
$sb = {
write-output "Testing 1"
write-output "Testing 2"
throw " Exception in sb"
}
$PowerShell = [powershell]::Create()
[void]$PowerShell.AddScript($sb)
$InputObject = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$OutputObject = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$Handle = $PowerShell.BeginInvoke($InputObject,$OutputObject)
Calling EndInvoke() will give you the error message:
PS C:\> $PowerShell.EndInvoke($Handle)
Exception calling "EndInvoke" with "1" argument(s): " Exception in sb"
At line:1 char:1
+ $PowerShell.EndInvoke($Handle)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : RuntimeException
But the output is stored in the $OutputObject buffer:
PS C:\> $InputObject
PS C:\> $OutputObject
Testing 1
Testing 2

'Run As Different Users' behaves differently with PowerShell

I'm using "Run As Different User" when running a PowerShell script, and it is behaving differently than when I run the script in a normal PowerShell Terminal. For example, if I try to run the following code in the "Run As" terminal, it runs into an error. But if I run it with a normal terminal it works just fine.
function Replace-Word(
[string]$Document,
[string]$FindText,
[string]$ReplaceText
)
{
$ReplaceAll = 2
$FindContinue = 1
$MatchCase = $False
$MatchWholeWord = $True
$MatchWildcards = $False
$MatchSoundsLike = $False
$MatchAllWordForms = $False
$Forward = $True
$Wrap = $FindContinue
$Format = $False
$Word = New-Object -comobject Word.Application
$Word.Visible = $False
$OpenDoc = $Word.Documents.Open($Document)
$Selection = $Word.Selection
$Selection.Find.Execute(
$FindText,
$MatchCase,
$MatchWholeWord,
$MatchWildcards,
$MatchSoundsLike,
$MatchAllWordForms,
$Forward,
$Wrap,
$Format,
$ReplaceText,
$ReplaceAll
) | Out-Null
$OpenDoc.Close()
$Word.quit()
}
Copy-Item "C:\Welcome.DOC" "C:\test.DOC"
Replace-Word -Document "C:\test.DOC" -FindText '<UserName>' -ReplaceText "JohnDoe"
Replace-Word -Document "C:\test.DOC" -FindText '<EmailAddress>' -ReplaceText "JohnDoe#example.com"
The errors I get when running as a different user are:
You cannot call a method on a null-valued expression.
At C:\Users\lbradstr\Desktop\TechRepo\NewEEsetup\NewUserSetup.ps1:2668 char:9
+ $Selection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\Users\lbradstr\Desktop\TechRepo\NewEEsetup\NewUserSetup.ps1:2670 char:9
+ $OpenDoc.Close()
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\Users\lbradstr\Desktop\TechRepo\NewEEsetup\NewUserSetup.ps1:2668 char:9
+ $Selection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\Users\lbradstr\Desktop\TechRepo\NewEEsetup\NewUserSetup.ps1:2670 char:9
+ $OpenDoc.Close()
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Both terminals are running the same version of PowerShell:
Major Minor Build Revision
----- ----- ----- --------
5 1 14409 1012
I would run this code in a normal terminal if I could, but this is only part of a larger script I am running. The rest of the script needs administrative privileges to run, which is why I use the "Run As" feature. Any ideas about why the code would execute differently between the two user accounts? Any suggestions would be very appreciated!
Everyone else's suggestion still apply (once permissions and ACL to the file has been sorted) and it is still giving you this error... THEN:
This is a classic case of locked file in Word. You need to release the COM Object from your last PowerShell session because it is probably still accessing the file and causing issues.
Once you release the COM Object or close all word processes, try running as again and it should work.

Null runtime exception when using IsNullOrEmpty

I am trying to init a config object with string value or file content value (if string variable is null or empty).
$ConfigObj = New-Object PSObject -Property #{
"Name" = $env:OOO_NAME
"Content"=
if([string]::IsNullOrEmpty($env:NOTE) -and [string]::IsNullOrEmpty($env:PUBLISH_FILEPATH))
{
Write-Host "Check input"
exit 1
}
elseif(![string]::IsNullOrEmpty($env:PUBLISH_NOTE))
{
$env:PUBLISH_NOTE ############# **it throws exception here.**
}
else
{
Get-Content ($env:PUBLISH_FILEPATH)
}
}
It works fine when this script execute by itself, but it yells RuntimeException after executing several PowerShell scripts. The following is exception info:
You cannot call a method on a null-valued expression.
+ $env:PUBLISH_NOTE
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
It really doesn't make any sense to me, since I use $env:{environment variable name} to access system environment variables and why doesn't it yell at earier lines such as
elseif(![string]::IsNullOrEmpty($env:PUBLISH_NOTE))
Please kindly explain what's the root case of this runtime exception.

Remove a PowerShell session variable?

I'm attempting to set and clear a session variable in a PowerShell module:
function Set-Variable
{
[CmdletBinding()]
param(
[string]$Value = $PSCmdlet.SessionState.PSVariable.Get('Value').Value
)
# if `Value` not supplied on the command line and not available in the session, prompt for it
if (!$PSCmdlet.SessionState.PSVariable.Get('Value') -And !$Value) {
$Value = Read-Host "Value"
}
# if `Value` has been supplied on the command line, save it in the session
if ($Value) {
$PSCmdlet.SessionState.PSVariable.Set('Value',$Value)
}
}
Export-ModuleMember Set-Variable
function Remove-Variable {
$PSCmdlet.SessionState.PSVariable.Remove('Value')
# also throws an exeception
# $PSCmdlet.SessionState.PSVariable.Set('Value',$null)
}
Export-ModuleMember Remove-Variable
Setting the value works as expect, however, removing the variable or setting its value to null produces an error:
PS> Remove-Variable
You cannot call a method on a null-valued expression.At
C:\Users\XXXX\Documents\WindowsPowerShell\Modules\foo\foo.psm1:39 char:5
+ $PSCmdlet.SessionState.PSVariable.Remove('Value')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
and:
You cannot call a method on a null-valued expression.At
C:\Users\XXXX\Documents\WindowsPowerShell\Modules\foo\foo.psm1:37 char:5
+ $PSCmdlet.SessionState.PSVariable.Set('Value',$null)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Is there a way to do this?

I need help find the error in powershell script

Trying to get my script to work and need some help here is my code.
#excel
#open ap
$XL = new-object -com "Excel.Application"
$XLbooks = $XL.workbooks
$netci = [system.Globalization.CompareInfo]"en-us"
$wkbk = $XLbooks.PSBase.GetType().Invokemember("Add",[Reflection.BindingFlags]::InvokeMethod,$null,$XLbooks,$null,$newci)
$sheet = $XLbooks.worksheets.item(1)
$sheet.name = "name"
$sheet.cells.item($row,1).formulalocal = "Fred Nurk"
$file = "c\windows\scripts\test.xlsx"
[void]$wkbk.PSBase.GetType().InvokeMember("SaveAs",[Reflection.BindingFlags]::InvokeMethod,$null,$wkbk,$file,$newci)
("Close",[Reflection.BindingFlags]::Invokemedthod,$null,$wkbk,0,$newci)
$XL.quit()
Errors:
Cannot convert the "en-us" value of type "System.String" to type "System.Globalization.CompareInfo".
At C:\scripts\test.ps1:5 char:44
+ $netci = [system.Globalization.CompareInfo] <<<< "en-us"
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
You cannot call a method on a null-valued expression.
At C:\scripts\test.ps1:7 char:34
+ $sheet = $XLbooks.worksheets.item <<<< (1)
+ CategoryInfo : InvalidOperation: (item:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Property 'name' cannot be found on this object; make sure it exists and is settable.
At C:\scripts\test.ps1:8 char:8
+ $sheet. <<<< name = "name"
+ CategoryInfo : InvalidOperation: (name:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
You cannot call a method on a null-valued expression.
At C:\scripts\test.ps1:9 char:18
+ $sheet.cells.item <<<< ($row,1).formulalocal = "Fred Nurk"
+ CategoryInfo : InvalidOperation: (item:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Exception calling "InvokeMember" with "6" argument(s): "Microsoft Excel cannot access the file 'C:\Users\Jared\Document
s\c\windows\scripts\5ADD7000'. There are several possible reasons:
The file name or path does not exist.
The file is being used by another program.
The workbook you are trying to save has the same name as a currently open workbook."
At C:\scripts\test.ps1:11 char:42
+ [void]$wkbk.PSBase.GetType().InvokeMember <<<< ("SaveAs",[Reflection.BindingFlags]::InvokeMethod,$null,$wkbk,$file,$n
ewci)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodTargetInvocation
The main issue you need to address is creating the CompareInfo. The first error tells you this line isn't working:
$netci = [system.Globalization.CompareInfo]"en-us"
So what you'll need to do is create the CompareInfo object this way:
$netci = ([system.Globalization.CultureInfo]"en-us").CompareInfo
Though instead of using this crazy way to create a workbook:
$wkbk = $XLbooks.PSBase.GetType().Invokemember("Add",[Reflection.BindingFlags]::InvokeMethod,$null,$XLbooks,$null,$newci)
...try this more sane way instead :D
$wkbk = $XL.workbooks.Add()
If you do it this way, you won't have to worry about creating the CompareInfo object.
The problem that jumps out at me is that $netci = [system.Globalization.CompareInfo]"en-us" is invalid syntax. You're not calling any method on the System.Globalization.CompareInfo class, you're just placing a string after it. PowerShell is interpreting [System.Globalization.CompareInfo] as a typecast operator, and complains that the string "en-us" can't be converted to the data type System.Globalization.CompareInfo - because that data type doesn't exist.
You need to invoke a method that operates on "en-us". You can get a list of methods from MSDN:
http://msdn.microsoft.com/en-us/library/system.globalization.compareinfo.aspx
Assuming that the method you want is GetCompareInfo (seems most likely to me - it returns a CompareInfo object), you'd write that line this way:
$netci = [System.Globalization.CompareInfo]::GetCompareInfo('en-us')
Note, BTW, that you have this variable as $netci when you create it, but as $newci in the rest of the script.
I haven't looked too deeply at the other errors, but they're probably a cascade effect from the failure to create $newci properly, so I suspect that if you fix this, the other errors will go away.