function function1(){
Param($a)
"YOU HAVE entered : $a"
$arr+=$a
$arr2.Add($a)
}
workflow wf{
Param($b)
Parallel{
sequence{
function1 $b
}
}
}
$arr = #()
$arr2 = [System.Collections.Arraylist]#()
wf -b 10
$arr
$arr2
The output I am getting as below
YOU HAVE entered : 10
Microsoft.PowerShell.Utility\Write-Error : You cannot call a method on a null-valued expression.
At wf:12 char:12
+
+ CategoryInfo : NotSpecified: (:) [Write-Error], RemoteException
+ FullyQualifiedErrorId : System.Management.Automation.RemoteException,Microsoft.PowerShell.Commands.WriteErrorCommand
+ PSComputerName : [localhost]
I am unable to update both the arrays which I declared outside the function and workflow.
Related
I'm facing an issue of getting all vms configuration ( using Get-ScVirtualMachine command) into an array from an input file.
The code is this one below
$VmsList = Get-Content C:\VmsList.txt
foreach($vm in $VmsList){
$Result += Get-SCVirtualMachine -Name $vm
}
And I have this error
Method invocation failed because [Microsoft.SystemCenter.VirtualMachineManager.VM] does not contain a method named 'op_Addition'.
At line:3 char:1
$Result += Get-SCVirtualMachine -Name $vm
+ CategoryInfo : InvalidOperation: (op_Addition:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [Microsoft.SystemCenter.VirtualMachineManager.VM] does not contain a method named 'op_Addition'.
At line:3 char:1
$Result += Get-SCVirtualMachine -Name $vm
+ CategoryInfo : InvalidOperation: (op_Addition:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Get-SCVirtualMachine : Cannot validate argument on parameter 'Name'. The character length (0) of the argument is too short. Specify an argument with a length that
is greater than or equal to "1", and then try the command again.
At line:3 char:39
$Result += Get-SCVirtualMachine -Name $vm
~~~
CategoryInfo : InvalidData: (:) [Get-SCVirtualMachine], ParameterBindingValidationException
FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.SystemCenter.VirtualMachineManager.Cmdlets.GetVMCmdlet
I forgot to declare the array $result = #()
I resolved the issue.
I have just encountered a very weird error: whenever I just add an empty line in a ps1 file which is otherwise working really fine, my script generates errors.
Here is the setup:
Because I had dependencies issues, I now have an Includes.ps1 file with that content:
$ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
. ("$ScriptDirectory\HelperFunctions.ps1")
. ("$ScriptDirectory\BuildParameters.ps1")
. ("$ScriptDirectory\Platform.ps1")
. ("$ScriptDirectory\Configuration.ps1")
. ("$ScriptDirectory\Action.ps1")
. ("$ScriptDirectory\Backup.ps1")
I have a Package.ps1 file which includes that file, and does the stuff of instanciating the needed classes and make them work together:
$ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
. ("$ScriptDirectory\Includes.ps1")
Clear-Host
$Parameters = New-Object -TypeName "BuildParameters"
$user_variables_path = "./UserVariables.ps1"
if ( Test-Path $user_variables_path )
{
. $user_variables_path
}
$Parameters.ValidateParameters()
$PlatformClass = $PlatformFactory.MakePlatform( $Parameters.Platform )
$PlatformClass.ValidateParameters( $Parameters )
$ConfigurationClass = $ConfigurationFactory.MakeConfiguration( $Parameters.Configuration )
$ConfigurationClass.ValidateParameters( $Parameters )
$ActionClass = $ActionsFactory.MakeAction( $Parameters.Action, $PlatformClass, $ConfigurationClass, $Parameters )
$ActionClass.ValidateParameters()
$Backup = [ Backup ]::new( $Parameters, $PlatformClass )
$Backup.ValidateParameters();
$ActionClass.Execute()
if ( $Parameters.BackupVersion )
{
$Backup.BackupVersion()
}
Here is the Platforms.ps1 file which gives me errors when I edit it:
class Platform
{
[Boolean] $CanBePatched
[Boolean] $CanCompressData
Platform()
{
$this.CanBePatched = $false
$this.CanCompressData = $true
}
[void] ValidateParameters( [BuildParameters] $Parameters )
{
}
}
class PlatformWin64 : Platform
{
PlatformWin64()
{
}
}
class PlatformXboxOne : Platform
{
PlatformXboxOne()
{
}
}
class PlatformSwitch : Platform
{
PlatformSwitch()
{
$this.CanBePatched = $true
}
[void] ValidateParameters( [BuildParameters] $Parameters )
{
if ( [string]::IsNullOrEmpty( $Parameters.Region ) )
{
WriteErrorAndExit( "You need to specify a region for the PS4" )
}
}
}
class PlatformPS4 : Platform
{
PlatformPS4()
{
$this.CanBePatched = $true
$this.CanCompressData = $false
}
[void] ValidateParameters( [BuildParameters] $Parameters )
{
if ( [string]::IsNullOrEmpty( $Parameters.Region ) )
{
WriteErrorAndExit( "You need to specify a region for the PS4" )
}
}
}
class PlatformFactory
{
[Platform] MakePlatform( [String] $name )
{
return (New-Object -TypeName "Platform$name")
}
}
$PlatformFactory = [PlatformFactory]::new()
When I change the contents of that file, even by adding empty lines, running the script gives me those errors:
Cannot convert argument "Platform", with value: "PlatformWin64", for
"MakeAction" to type "Platform": "Cannot convert the "PlatformWin64" value
of type "PlatformWin64" to type "Platform"."
At F:\Projects\RWC\BuildScripts\Utils\Package.ps1:55 char:1
+ $ActionClass = $ActionsFactory.MakeAction( $Parameters.Action, $Platf ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
You cannot call a method on a null-valued expression.
At F:\Projects\RWC\BuildScripts\Utils\Package.ps1:56 char:1
+ $ActionClass.ValidateParameters()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Cannot convert argument "Platform", with value: "PlatformWin64", for
".ctor" to type "Platform": "Cannot convert the "PlatformWin64" value of
type "PlatformWin64" to type "Platform"."
At F:\Projects\RWC\BuildScripts\Utils\Package.ps1:58 char:1
+ $Backup = [ Backup ]::new( $Parameters, $PlatformClass )
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
You cannot call a method on a null-valued expression.
At F:\Projects\RWC\BuildScripts\Utils\Package.ps1:59 char:1
+ $Backup.ValidateParameters();
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At F:\Projects\RWC\BuildScripts\Utils\Package.ps1:61 char:1
+ $ActionClass.Execute()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At F:\Projects\RWC\BuildScripts\Utils\Package.ps1:65 char:5
+ $Backup.BackupVersion()
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Well it turns out I had to close the powershell command line and run it again to have my modifications not generate any errors.
That post helped me find the cause...
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?
Consider the following script
#requires -version 2.0
[CmdletBinding()]
param
(
)
$script:ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
function PSScriptRoot { $MyInvocation.ScriptName | Split-Path }
function ThrowFunction($i)
{
"ThrowFunction $i"
$someNonExistingVariable
}
#(1, 2, 3) | ForEach-Object -Process { ThrowFunction $_ }
When we run it we get
C:\dev> .\MyScript.ps1
ThrowFunction 1
ForEach-Object : The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At C:\dev\MyScript.ps1:18 char:28
+ #(1, 2, 3) | ForEach-Object <<<< -Process { ThrowFunction $_ }
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:Token) [ForEach-Object], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined,Microsoft.PowerShell.Commands.ForEachObjectCommand
As you see it reports the problem in line #18
But the actual problem is in the line #15
I found that if we change Line 8:
$script:ErrorActionPreference = "Continue"
We get
C:\dev> .\MyScript.ps1
ThrowFunction 1
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At C:\dev\MyScript.ps1:15 char:29
+ $someNonExistingVariable <<<<
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:Token) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
ThrowFunction 2
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At C:\dev\MyScript.ps1:15 char:29
+ $someNonExistingVariable <<<<
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:Token) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
ThrowFunction 3
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At C:\dev\MyScript.ps1:15 char:29
+ $someNonExistingVariable <<<<
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:Token) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
And you see that now line 15 is reported as expected.
Now the question is how to get the proper line and have “Stop” behavior.
I tried many approaches and none of them worked for me.
I tried
trap { throw $_ }
trap { $_.InvocationInfo }
trap { Get-PSCallStack }
but none of them gets the proper line
Then I tried to switch
$script:ErrorActionPreference = "Continue"
and found that as soon as I add any trap, the wrong line is being reported again.
So I am still looking for a working solution...
Thanks to #Keith Hill, I found a solution
The magic line is
trap { throw $Error[0] }
This script
#requires -version 2.0
[CmdletBinding()]
param
(
)
$script:ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
function PSScriptRoot { $MyInvocation.ScriptName | Split-Path }
trap { throw $Error[0] }
function ThrowFunction($i)
{
"ThrowFunction $i"
$someNonExistingVariable
}
#(1, 2, 3) | ForEach-Object -Process { ThrowFunction $_ }
returns
C:\Dev> .\MyScript.ps1
ThrowFunction 1
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At C:\Dev\MyScript.ps1:17 char:29
+ $someNonExistingVariable <<<<
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:Token) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
Great!
Even though you've set strictmode to Latest, the $someNonExistingVariable does not generate a terminating error. It just writes to the Error stream. By setting ErrorActionPreference to Stop, you now have Foreach-Object converting the non-terminating error into a terminating error. That is why the error indicates line 18 - the Foreach-Object cmdlet.
If you look in the $Error collection, assuming you Clear() it first, you would see two errors. The latest is in $Error[0] - this is the terminating error thrown by Foreach-Object. $Error[1] is the non-terminating error written by the attempt to access an undefined variable. It has the right line number - 15.
You can access the ScriptStackTrace like so:
PS C:\> $error[0].errorRecord.ScriptStackTrace
at ThrowFunction, C:\Users\hillr\ErrorLine.ps1: line 15
at <ScriptBlock>, C:\Users\hillr\ErrorLine.ps1: line 18
at <ScriptBlock>, C:\Users\hillr\ErrorLine.ps1: line 18
You can you Try {} Catch {} instead :
#requires -version 2.0
[CmdletBinding()]
param
(
)
$script:ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
function PSScriptRoot { $MyInvocation.ScriptName | Split-Path }
function ThrowFunction($i)
{
"ThrowFunction $i"
Try {
$someNonExistingVariable
}
Catch { # The variable $_ represents the error that is caught
Write-Output $_
}
}
#(1, 2, 3) | ForEach-Object -Process { ThrowFunction $_ }
And the resulting output gives the correct line number :
ThrowFunction 1
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At line:16 char:9
+ $someNonExistingVariable
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:String) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
ThrowFunction 2
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At line:16 char:9
+ $someNonExistingVariable
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:String) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
ThrowFunction 3
The variable '$someNonExistingVariable' cannot be retrieved because it has not been set.
At line:16 char:9
+ $someNonExistingVariable
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (someNonExistingVariable:String) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
i have a problem with my PS code, i have to start my tests on browsers every tuesday in teamcity! and i wrote the function which goes on my server with credentials and try to make my tests on it
function HTTP-GetRequest($url, $username, $password)
{
$properties = Resolve-Path "C:\Users\Uladzimir_Vaitsiakho\Documents\CI\Build\CI_2.0\vsphere\properties.ps1"
Write-Host $properties
. $properties
$webRequest = [System.Net.WebRequest]::Create($url)
$webRequest.Credentials = New-Object System.Net.NetworkCredential -ArgumentList $username, $password
$webRequest.PreAuthenticate = $true
$webRequest.Headers.Add("AUTHORIZATION", "Basic");
[System.Net.WebResponse] $resp = $webRequest.GetResponse();
$rs = $resp.GetResponseStream();
[System.IO.StreamReader] $sr = New-Object System.IO.StreamReader -argumentList $rs;
[string] $results = $sr.ReadToEnd();
return $results
}
if (($today.DayOfWeek) -eq "Tuesday")
{
if ($env:Browser -eq "Firefox"){
$url = "http://1111111/httpAuth/action.html?add2Queue=bt6&&env.name=Browser&env.value=Chrome"
HTTP-GetRequest $url, $teamcity_username, $teamcity_password
Write-Host $teamcity_password
Write-Host $teamcity_username
}
if ($env:Browser -eq "Chrome"){
$url = "http://11111/httpAuth/action.html?add2Queue=bt6&&env.name=Browser&env.Value=InternetExplorer"
HTTP-GetRequest $url, $teamcity_username, $teamcity_password
}
}
And have got the next output with troubles, but file with properties and credentials i gave to my function, what's can be wrong?!
Cannot convert argument "0", with value: "System.Object[]", for "Create" to type "System.Uri": "Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Uri"."
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:6 char:47
+ $webRequest = [System.Net.WebRequest]::Create <<<< ($url)
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Property 'Credentials' cannot be found on this object; make sure it exists and is settable.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:7 char:14
+ $webRequest. <<<< Credentials = New-Object System.Net.NetworkCredential -ArgumentList $username, $password
+ CategoryInfo : InvalidOperation: (Credentials:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Property 'PreAuthenticate' cannot be found on this object; make sure it exists and is settable.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:10 char:14
+ $webRequest. <<<< PreAuthenticate = $true
+ CategoryInfo : InvalidOperation: (PreAuthenticate:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
You cannot call a method on a null-valued expression.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:11 char:25
+ $webRequest.Headers.Add <<<< ("AUTHORIZATION", "Basic");
+ CategoryInfo : InvalidOperation: (Add:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:13 char:58
+ [System.Net.WebResponse] $resp = $webRequest.GetResponse <<<< ();
+ CategoryInfo : InvalidOperation: (GetResponse:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:14 char:31
+ $rs = $resp.GetResponseStream <<<< ();
+ CategoryInfo : InvalidOperation: (GetResponseStream:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.IO.StreamReader.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:15 char:43
+ [System.IO.StreamReader] $sr = New-Object <<<< System.IO.StreamReader -argumentList $rs;
+ CategoryInfo : ObjectNotFound: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : CannotFindAppropriateCtor,Microsoft.PowerShell.Commands.NewObjectCommand
You cannot call a method on a null-valued expression.
At C:\Users\Uladzimir_Vaitsiakho\Documents\qw.ps1:16 char:35
+ [string] $results = $sr.ReadToEnd <<<< ();
+ CategoryInfo : InvalidOperation: (ReadToEnd:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Currently the call to HTTP-GetRequest is passing an array of objects ($url, $teamcity_username , $teamcity_password) to the function. Remove the commas from your function call:
HTTP-GetRequest $url $teamcity_username $teamcity_password