Surprises in Powershell coding

satya - 2/22/2020, 5:46:28 PM

Link to My Coding journal for powershell

Link to My Coding journal for powershell

satya - 2/22/2020, 5:46:49 PM

Yes. There are quite a few surprises

Yes. There are quite a few surprises

satya - 2/22/2020, 5:50:06 PM

Not allocating output from a function


function f1()
{
    #good
    $x = f2 -arg1 "abc"

    #it is a bad idea not to consume what f2 returns
    f2 -arg1 "abc"

    return "somevalue"
}

#f1 may be returning a lot more if not

satya - 2/22/2020, 5:50:50 PM

Calling a method with ()


#do this
$x = f2 -arg1 "abc"

#not
f2("abc")

satya - 2/22/2020, 5:53:05 PM

The Format-Table like functions may not work inside class function


class {
[void]f1()
  {
     #this won't display
     #this would if this function is outside
     $somearray | select-object .... | Format-Table

     #this would display also if it is outisde
     #but not inside a function in a class
     $somearray
  }
}

satya - 2/22/2020, 5:54:18 PM

Mistaking comparison ops


if ($count > 10)
{
  break
}

when it should be

if ($count -gt 10)
{
  break
}

satya - 2/22/2020, 5:55:35 PM

Passing a param that doesnt exist by mistake or otherwise


function f1($a,$b){}

Calling it as 

f1 -c "blah"

satya - 3/14/2020, 4:57:46 PM

Misspellings is a BIG BUG....Be aware

Misspellings is a BIG BUG....Be aware

satya - 3/20/2020, 2:35:16 PM

Use of function call braces

They have a special meaning in powerhell

Not used for calling functions in powershell native code

However they are used when calling class methods or underlying dotnet classes

I get tripped up all the time and end up using braces when I shouldn't be

this results in significant surprises as they do actually work most of the time!!!

satya - 3/30/2020, 2:48:01 PM

Understand scopes: especially script: scope

Understand scopes: especially script: scope

satya - 3/30/2020, 2:52:16 PM

On scopes briefly

a child scope can read its parent scopes variables. It cannot update

a child scope will hide a parent scope if the name is duplicate

You can refer to your immediate parent scope using scope:

that is how you can change a value of a variable in its parent scope

this is useful in your closures

satya - 4/2/2020, 10:49:51 AM

stdin redirection will not work with Read-Host in powershell

stdin redirection will not work with Read-Host in powershell

Search for: stdin redirection will not work with Read-Host in powershell

satya - 4/2/2020, 10:49:55 AM

and that sucks!

and that sucks!

satya - 4/2/2020, 10:50:56 AM

One is advised to use params instead....

but that is not the most flexible thing to do and paints one into a convention, I am afraid!!!

satya - 4/2/2020, 11:21:36 AM

Do pipes use stdin and stdout in powershell?

Do pipes use stdin and stdout in powershell?

Search for: Do pipes use stdin and stdout in powershell?

satya - 4/4/2020, 10:16:44 PM

Missing braces...:(


if ($script:plantName -ne "sidrap")
    {
        $ea.addError("Plant name is not sidrap" #missing brace here
    }

satya - 4/4/2020, 10:30:52 PM

Again the inconsistency of braces got me ...


if ($ea.areThereErros -eq $true)
    {
        $ea.printErrorArray
        return $false
    }

The $ea is an object. so the function areThereErrors needs to be arethereerrors(). Missing them will invalidate the boolean check.

satya - 4/4/2020, 10:38:23 PM

If gets confused again


function validateConfig() {}

#with out the braces around the function
#it evaluates to true

if ((validateConfig) -eq $false)
    {
        p -message "Validating failed. Returning"
        return
    }

satya - 4/4/2020, 10:39:49 PM

So ... in short pay special attention to if clauses that use output from functions

So ... in short pay special attention to if clauses that use output from functions

satya - 4/12/2020, 12:43:14 PM

Notice this


pe -message "Exception message: $($er.Exception.Message)"

with out the brackets, .Exception.Message are considered literals

satya - 4/12/2020, 12:48:44 PM

Including a script twice in the same session

1. Casting a class object even to itself will throw an exception

2. So include it only once

3. This normally shows up in embedded powershell scripts in vscode. Just close vscode and reopen to deal with it.

satya - 4/12/2020, 5:25:08 PM

Can you spot what a likely error is


$myargs = @{
    $paramPlantName = $dPlantName
    $paramOverridePlantName =$dOverridePlantName
    $paramPlantDataFileType = $dPlantDataFileType

    $paramPlantBaseDir = $dPlantBaseDir
    $paramMaxFilesToProcess = $dMaxFilesToProcess

    $paramRunLocal = $false
}

That is a hashtable initialization. The left hand side are keys. It is unlikely that they are variables. So the $sign needs to be removed. I run into this often.

satya - 4/18/2020, 10:53:37 AM

How powershell uses console is outright confusing

How powershell uses console is outright confusing

satya - 4/18/2020, 10:53:59 AM

read-host, write-host and the pipeline printing are not synchronized

read-host, write-host and the pipeline printing are not synchronized

satya - 4/19/2020, 10:16:10 AM

Spelling mistakes will kill you

1. Not that I know there is a warning for using a variable that is not defined in vscode.

2. But there is a warning for a variable that is not used

3. So pay attention to the unused variables as they indicate what should be used but were not

satya - 4/19/2020, 10:29:08 AM

How to print a hashtable


$myHashTable = @{a="b";c="d"}

#not fruitful
$myHashTable.tostring()

#but you can do this
$myHashTable | Format-table

#or just on a line by itself
$myHashtable

satya - 4/19/2020, 10:47:11 AM

docs on hashtable powershell

docs on hashtable powershell

satya - 4/27/2020, 7:23:57 PM

Big surprise, functions that return


function getInverterDataArray($invHt)
{
    $keys = $invHt.Keys
    [System.Collections.ArrayList]$invArrayList = [System.Collections.ArrayList]@()
        
    foreach ($invName in $keys)
    {
        $individualInvArray = $invHt[$invName]
        $m = Measure-Object -Data $individualInvArray -property tag_value
        
        [classInverterData]$inverterData = [classInverterData]::new()
        $inverterData.name = $invName
        $inverterData.numOfPoints = $m.count
        $inverterData.averageEnergy = $m.average
        $inverterData.totalEnergy = $m.sum
    #The below can create havoc as well with out $result
        $result = $invArrayList.Add($inverterData)
    }
    #The below can create havoc
    $invArrayList | Format-table
    return $invArrayList
}

satya - 5/2/2020, 11:13:57 AM

PSCustomPS Object may look like a hashtable

there is no niceway to see it as a hashtable!

satya - 9/13/2020, 2:27:12 PM

Dealing with exceptions

1. You need to study how exceptions work

2. To stop a script or not on exceptions

3. how to print these exceptions

satya - 9/22/2020, 10:48:51 AM

Tricky Including other powershell scripts

1. Not to duplicate running of reusable scripts

2. How best to do this

3. My original trick is sufficiently dangerous and may break things

4. look for a better approach.