Powershell coding journal

satya - 1/16/2020, 10:53:47 AM

Comparing boolean values


Write-Host "\nReporting on the results of the ping status"
if ($netResult.PingSucceeded -eq $true)
{
         Write-Host "Ping succeeded. Details will follow"
}
else 
{
         Write-Host "ping failed. Details will follow"
}

satya - 1/16/2020, 10:54:14 AM

How to insert a new line character in a powershell string write-host

How to insert a new line character in a powershell string write-host

Search for: How to insert a new line character in a powershell string write-host

satya - 1/16/2020, 11:29:11 AM

How to add a new line in a powershell string


function startSection($line)
{
   #Start a new line
   #Uses backtick character as the escape
   #Also called grave accent
   Write-Host "`n$line"
}

satya - 1/16/2020, 11:29:26 AM

Special characters are documented here

Special characters are documented here

satya - 1/30/2020, 9:08:49 PM

winscp module is documented here

winscp module is documented here

satya - 1/30/2020, 9:12:50 PM

Find-Module to discover modules


#Find modules that are named like ftp in the galleries
find-module -name *ftp*

#Some module may not be named that way
find-module -name winscp

satya - 1/30/2020, 9:14:18 PM

To search for modules in powershell gallery

To search for modules in powershell gallery

satya - 2/2/2020, 4:29:33 PM

line continuation in powershell

line continuation in powershell

Search for: line continuation in powershell

satya - 2/2/2020, 4:30:14 PM

it appears to be backtick

it appears to be backtick

satya - 2/2/2020, 5:03:08 PM

About throw

About throw

satya - 2/2/2020, 5:29:28 PM

Surprises, surprises


if(somefunc($input) - eq $false)
{
    //do something
}

#that is a problem

it should be

if((somefunc($input)) - eq $false)
{
    //do something
}

Notice extra brackets

Ideally it should be

if((somefunc -input $input) - eq $false)
{
    //do something
}

This is to do with grouping

satya - 2/3/2020, 11:59:05 AM

How to get a credentials object from the environment


<#
# *************************************************
#
# Read Credentials for an ftp host
#
# A formulated $credential object is returned
# Object type is:
# System.Management.Automation.PSCredential
#
# From the environment:

# the following from the environment
#
# Assuming an ftp host name is: ftphost
# ftp.ftphost.host
# ftp.ftphost.username
# ftp.ftphost.password
#
# *************************************************
#>
function isValid($somestring)
{
    if ($somestring -eq $null)
    {
        return $false
    }
    
    if ($something -eq "")
    {
        return $false`
    }
    return $true
}

function getEnvVariable($name)
{
    $valid = isValid($name)
    if ($valid -eq $false)
    {
        throw "Invalid environment variable name: null or empty"
    }
    $value = Get-ChildItem -Path "Env:$name" -ErrorAction Ignore
    $returnValue = $value.value

    if ((isValid($returnValue)) -eq $fasle)
    {
        throw "Empty environment output for variable:$name"
    }
    return $returnValue
}


function getCredentials($hostname)
{
    $env_username = "ftp." + $hostname + ".username"
    $env_password = "ftp." + $hostname + ".password"

    $username = getEnvVariable -name $env_username
    $passwordPlain = getEnvVariable -name $env_password

    $password = ConvertTo-SecureString $passwordPlain -AsPlainText -Force

    $credential = New-Object System.Management.Automation.PSCredential($username, $password)
    return $credential
}

$credentials = getCredentials -hostname "ftphost"
#Will loo

Write-Host "Username $($credentials.username)"
Write-Host "Password: $($credentials.password)"

satya - 2/5/2020, 1:00:51 AM

How to invoke a REST call from powershell: microsoft docs Invoke-RESTMethod

How to invoke a REST call from powershell: microsoft docs Invoke-RESTMethod

satya - 2/5/2020, 2:32:24 PM

ISO Date and time format

ISO Date and time format

Search for: ISO Date and time format

satya - 2/5/2020, 2:37:36 PM

Two examples


//Notice the T
2019-09-01T00:00:00.000
YYYY-MM-DDTHH:MM:SS.SSS

or

//I have seen this work without the T
2019-09-01 00:00:00.000
YYYY-MM-DD HH:MM:SS.SSS

satya - 2/5/2020, 2:38:27 PM

web reference for ISO date time format

web reference for ISO date time format

satya - 2/5/2020, 2:39:19 PM

is T optional in ISO date formats?

is T optional in ISO date formats?

Search for: is T optional in ISO date formats?

satya - 2/5/2020, 2:39:36 PM

Optional T discussion on SOF

Optional T discussion on SOF

satya - 2/5/2020, 6:06:29 PM

Here is a CSV to JSON converter online

Here is a CSV to JSON converter online

satya - 2/5/2020, 6:07:34 PM

table to class json creators

table to class json creators

Search for: table to class json creators

satya - 2/5/2020, 6:08:07 PM

powershell class definitions

powershell class definitions

Search for: powershell class definitions

satya - 2/5/2020, 6:09:39 PM

Powershell classes docs

Powershell classes docs

satya - 2/5/2020, 6:09:59 PM

Example


class Device {
    [string]$Brand
    [string]$Model
    [string]$VendorSku
}

$device = [Device]::new()
$device.Brand = "Microsoft"
$device.Model = "Surface Pro 4"
$device.VendorSku = "5072641000"

$device

satya - 2/5/2020, 6:36:01 PM

How to call a storedproc from powershell

How to call a storedproc from powershell

Search for: How to call a storedproc from powershell

satya - 2/5/2020, 6:46:13 PM

This is a good example

This is a good example

satya - 2/5/2020, 6:49:35 PM

t-sql sample stored procedures

t-sql sample stored procedures

Search for: t-sql sample stored procedures

satya - 2/6/2020, 12:36:38 AM

Here is the doc for System.Data.SqlClient.SqlCommand

Here is the doc for System.Data.SqlClient.SqlCommand

satya - 2/6/2020, 12:40:42 AM

Reading from a stored proc from Invoke-SQLCommand

Reading from a stored proc from Invoke-SQLCommand

satya - 2/6/2020, 12:41:10 AM

Invoke-SQLCommand powershell

Invoke-SQLCommand powershell

Search for: Invoke-SQLCommand powershell

satya - 2/6/2020, 12:42:19 AM

Docs on invoke-sqlcommand

Docs on invoke-sqlcommand

satya - 2/7/2020, 10:33:56 AM

strangeness and rules of braces in powershell

strangeness and rules of braces in powershell

Search for: strangeness and rules of braces in powershell

satya - 2/7/2020, 10:34:37 AM

braces


#problem calling a function
$csvFileList = getStagedCSVFiles()


#not a problem
$csvFileList = getStagedCSVFiles

satya - 2/7/2020, 10:34:51 AM

How to read records from csv file in powershell

How to read records from csv file in powershell

Search for: How to read records from csv file in powershell

satya - 2/7/2020, 10:36:25 AM

Import-CSV Commandlet

Import-CSV Commandlet

satya - 2/7/2020, 10:52:40 AM

PSCustom Object to a typed object in powershell

PSCustom Object to a typed object in powershell

Search for: PSCustom Object to a typed object in powershell

satya - 2/7/2020, 10:54:20 AM

Nice article on strong types

Nice article on strong types

satya - 2/7/2020, 11:10:56 AM

hashtables, dictionaries, objects

hashtables, dictionaries, objects

satya - 2/7/2020, 11:11:19 AM

Add-Type commandlet

Add-Type commandlet

Search for: Add-Type commandlet

- 2/7/2020, 11:39:57 AM

You can extend a string this way


$somestring = @"
   line1
  line2
line3
This termination must be the first 2 characters
"@

annonymous - 2/7/2020, 11:41:15 AM

Powershell datetime type

Powershell datetime type

Search for: Powershell datetime type

annonymous - 2/7/2020, 11:42:32 AM

A quick external reference for Powershell types

A quick external reference for Powershell types

annonymous - 2/7/2020, 11:43:42 AM

quick ref


[string]    Fixed-length string of Unicode characters
 [char]      A Unicode 16-bit character
 [byte]      An 8-bit unsigned character

 [int]       32-bit signed integer
 [long]      64-bit signed integer
 [bool]      Boolean True/False value

 [decimal]   A 128-bit decimal value
 [single]    Single-precision 32-bit floating point number
 [double]    Double-precision 64-bit floating point number
 [DateTime]  Date and Time

 [xml]       Xml object
 [array]     An array of values
 [hashtable] Hashtable object

satya - 2/7/2020, 5:18:28 PM

Tokenizing strings in powershell

Tokenizing strings in powershell

Search for: Tokenizing strings in powershell

satya - 2/7/2020, 6:25:26 PM

String split Example in Powershell


function extractPlantnameFromFilename($basefilename)
{
    [String[]]$tokens = $basefilename -split "_"
    if ($tokens.Count -lt 1)
    {
        throw "Filename does not contain plantname"
    }
    return $tokens.Item(0)
}

satya - 2/7/2020, 6:26:20 PM

Get-Date Datetime in powershell

Get-Date Datetime in powershell

satya - 2/7/2020, 6:33:09 PM

Date formats for Powershell

Date formats for Powershell

satya - 2/7/2020, 6:35:36 PM

Production


Get-Date -Format s
2020-02-07T18:34:48

satya - 2/7/2020, 6:55:02 PM

An example of using FileSystemInfo and FileInfo


function processStagedFiles()
{
    $csvFileList = getStagedCSVFiles
    #printSimpleTypeInfo($csvFileList)

    foreach($file in $csvFileList)
    {
        #printSimpleTypeInfo($file)
        [System.IO.FileSystemInfo]$file1 = $file
        $fullFilenamne = $file1.FullName
        $baseFilename = $file1.BaseName
        $filesize = $file1.Length
        p -message "Going to process $fullFilenamne"

        processFile -fullFilename $fullFilenamne `
            -basefilename $baseFilename `
            -filesize $filesize
    }
}

satya - 2/8/2020, 11:51:07 AM

convert datetime to ISO format in powershell

convert datetime to ISO format in powershell

Search for: convert datetime to ISO format in powershell

satya - 2/8/2020, 11:53:04 AM

Get-date with format


Get-Date -Format "dddd MM/dd/yyyy HH:mm K"

Tuesday 06/25/2019 16:17 -07:00

satya - 2/8/2020, 12:15:24 PM

More on dates and iso time


function testDates()
 {
     [DateTime]$datetime = Get-Date

     $ut = $datetime.ToUniversalTime()
     p -message "Universal time $ut"
     #Universal time 02/08/2020 17:13:52

     $iso = $datetime.ToString("yyyy-MM-ddTHH:MM:ss.mmm")
     p -message "iso time $iso"
     #iso time 2020-02-08T12:02:52.13
    }

satya - 2/8/2020, 12:47:00 PM

In VSCdoe, use Ctrl-B to gain more space

In VSCdoe, use Ctrl-B to gain more space

satya - 2/8/2020, 5:39:38 PM

A discussion on types and import-csv commandlet

A discussion on types and import-csv commandlet

satya - 2/8/2020, 5:39:54 PM

data types for import-csv commandlet

data types for import-csv commandlet

Search for: data types for import-csv commandlet

satya - 2/8/2020, 6:36:23 PM

Some more date code


function testImportCSV()
{
    [Object[]]$rows = Import-Csv -Path $g_testCSVFile
    $numOfRows = $rows.Count
    p -message "Number of rows read $numOfRows"
    foreach ($row in $rows)
    {

        #printSimpleTypeInfo -inputObject $row.datetime
        #This indicates it is a string

        p -message "As a string $($row.datetime)"
        #As a string 2019-10-22 08:30:00

        $datetime = Get-Date -Date $row.datetime
        p -message "As a UTC $($datetime)"
        #As a UTC 10/22/2019 08:30:00
    }

}

satya - 2/9/2020, 3:12:50 PM

How to pass command line arguments to a powershell

How to pass command line arguments to a powershell

Search for: How to pass command line arguments to a powershell

satya - 2/9/2020, 3:15:27 PM

A nice alternative to calling functions with parameters

A nice alternative to calling functions with parameters

satya - 2/9/2020, 3:17:49 PM

Apparently you can do this


f1 -a1 10 -a2 "satya" -a3 12

Instead

$args = @{
  a1=10
  a2 = "satya"
  a3 = 12
}

f1 @arrgs

:)

satya - 2/9/2020, 3:20:58 PM

How to work with command line arguments:SOF

How to work with command line arguments:SOF

satya - 2/9/2020, 4:42:39 PM

about param powershell

about param powershell

Search for: about param powershell

satya - 2/9/2020, 4:51:10 PM

how to test the number of arguments passed in powershell

how to test the number of arguments passed in powershell

Search for: how to test the number of arguments passed in powershell

satya - 2/9/2020, 5:05:15 PM

How to call one powershell script from another powershell script

How to call one powershell script from another powershell script

Search for: How to call one powershell script from another powershell script

satya - 2/9/2020, 5:06:51 PM

what is CmdletBinding in powershell

what is CmdletBinding in powershell

Search for: what is CmdletBinding in powershell

satya - 2/9/2020, 5:09:08 PM

what is $PSScriptRoot

what is $PSScriptRoot

Search for: what is $PSScriptRoot

satya - 2/9/2020, 5:10:07 PM

Invoke-Expression Commandlet

Invoke-Expression Commandlet

Search for: Invoke-Expression Commandlet

satya - 2/9/2020, 5:22:40 PM

how to include one .ps1 file from another

how to include one .ps1 file from another

Search for: how to include one .ps1 file from another

satya - 2/9/2020, 5:23:10 PM

how to include one .ps1 file from another: SOF to the resscue

how to include one .ps1 file from another: SOF to the resscue

satya - 2/9/2020, 5:28:03 PM

The dot operator in powershell

The dot operator in powershell

Search for: The dot operator in powershell

satya - 2/9/2020, 5:29:08 PM

This seem to work


$scriptDir="C:\satya\....\utils"

$psutils = "$scriptDir\psutils.ps1"
. $psutils

#All functions in psutils.ps1 is now visible

satya - 2/9/2020, 7:02:23 PM

Perhaps one way to include common functions


#*********************************************
#  Execute Common libraries: Include this one at the top
#********************************************
function getScriptDir() {
    $script_path    =  $myinvocation.PSCommandPath
    $script_folder  = split-path $script_path -parent
    $script_name    = split-path $script_path -leaf    
    return $script_folder
}
$libScriptDir = getScriptDir

if ($psutilsIncluded -eq $null)
{
    Write-Host "Invoking psutils.ps1 Common utilities"
    ."$libScriptDir\psutils.ps1"
}
#*********************************************
#  Execute Common libraries
#********************************************

Please note, modules may still be the way to go.

satya - 2/9/2020, 7:06:22 PM

Nature of duplicate function names in powershell

Nature of duplicate function names in powershell

Search for: Nature of duplicate function names in powershell

satya - 2/9/2020, 7:06:31 PM

This is allowed


function f1()
{
    Write-host "first time"
}

function f1()
{
    Write-host "second time"
}

#Allowed to have duplicates
#Last one gets the preference
f1

satya - 2/9/2020, 10:05:34 PM

$arsgs is an automatic variable. Here are the docs

$arsgs is an automatic variable. Here are the docs

satya - 2/9/2020, 10:09:34 PM

Args is much better explained here

Args is much better explained here

satya - 2/9/2020, 10:38:03 PM

Curious case of $args


#In some .ps1 file you want to test args

function testargsBad()
{
    p -message "From test args"
    p -message "Number of args: $($args.Count)"
}

function testargsGood($myargs)
{
    p -message "From test args"
    p -message "Number of args: $($myargs.Count)"
}

#Try to call a function to examine args
testArgsBad
testargsGood -myargs $args

satya - 2/9/2020, 10:40:02 PM

This is because

1. $args is a locally scoped variable in every function including the script itself and all its internal functions

2. that is why what is passed in, into the script file is only valid at the global scope for that script and not at the individual function level scope

3. Not directly related, but on a side note, the $args only contain unnamed variables, that is those that are not declared in params or explicitly qualified with their argument name.

satya - 2/9/2020, 10:58:27 PM

Nature of unnamed arguments

1. If you pass 10 arguments, say, all unnamed

2. say the script has 4 named params as input

3. Then the args array will 6 unnamed params in it

4. The first 4, if they match the names, are assigned to named variables. If they don't match the variable is not initialized. However even then, only the last 6 are considered unnamed.

satya - 2/10/2020, 10:32:36 AM

How do I redirect stdout and stderr from powershell scripts

How do I redirect stdout and stderr from powershell scripts

Search for: How do I redirect stdout and stderr from powershell scripts

satya - 2/10/2020, 10:33:32 AM

Redirection options in powershell are documented here

Redirection options in powershell are documented here

satya - 2/10/2020, 10:42:31 AM

Write-Information is documented here

Write-Information is documented here

satya - 2/10/2020, 10:42:51 AM

This allows you to do


function Test-Info
{
    Get-Process P*
    Write-Information "Here you go"
}
Test-Info 6> Info.txt

satya - 2/10/2020, 10:42:58 AM

Notice the 6

Notice the 6

satya - 2/10/2020, 9:12:49 PM

How to declare an array in powershell

How to declare an array in powershell

Search for: How to declare an array in powershell

satya - 2/10/2020, 9:15:59 PM

arrays in powershell

arrays in powershell

satya - 2/10/2020, 10:28:51 PM

wonder if i can handle multiple errors this way


class ErrorArray {
    [String []]$errorArray = @()

    [void]addError($message)
    {
        $this.errorArray += ("Error:" + $message)
    }
    [bool] areThereErros()
    {
        if ($this.errorArray.Count -eq 0)
        {
            return $false
        }
        else {
            return $true
        }
    }

    [void] printErrorArray()
    {
        foreach($error in $this.errorArray)
        {
            p -message $error
        }
    }
}

function getANewErrorArray()
{
    return [ErrorArray]::new()
}

function testErrorArray() 
{
    [ErrorArray]$errorArray = getANewErrorArray
    $errorArray.addError("first one")
    $errorArray.addError("second one")
    if ($errorArray.areThereErros() -eq $true)
    {
        $errorArray.printErrorArray()
    }
}

satya - 2/10/2020, 10:29:21 PM

How to check for a file existence in powershell

How to check for a file existence in powershell

Search for: How to check for a file existence in powershell

satya - 2/10/2020, 10:30:16 PM

Test-Path docs

Test-Path docs

satya - 2/10/2020, 10:32:51 PM

example


[bool]$result = Test-Path -Path "C:\Documents and Settings\DavidC"

satya - 2/11/2020, 11:45:07 AM

Be careful with this


$dirDictionary = [ordered]@{
  c=33
  a=5
  b=10
}

#dirDictionary will keep the order

#But the following doesn't!!!
[System.Collections.Hashtable]$d = $dirDictionary;

satya - 2/11/2020, 12:50:41 PM

Scopes can throw you off. Docs on scope

Scopes can throw you off. Docs on scope

satya - 2/12/2020, 9:47:35 AM

GetType is documented here

GetType is documented here

satya - 2/12/2020, 9:54:19 AM

DO NOT USE () while calling powershell functions


function f1($somearg){}

Then do not call that as

f1($value) 

EVER

INSTEAD

f1 -somearg $value

satya - 2/12/2020, 10:20:56 AM

Understanding types and files returned by powershell


function countFiles($fileList)
{
    if ($fileList -eq $null)
    {
        return 0
    }
    $fullname = getTypeFullname -inputObject $fileList
    if ($fullname -eq 'System.Object[]')
    {
        [System.Object[]]$a = $fileList
        return $a.Count
    }
    if ($fullname -eq "System.IO.FileInfo")
    {
        return 1
    }
    return $null
}
function testFileList()
{
    hp -message "testing FileList object"
    gotoStageDirectory
    $csvFileList = getStagedCSVFiles

    printSimpleTypeInfo -inputObject $csvFileList

    if ($csvFileList -eq $null)
    {
        p -message "the file list is null"
        return
    }
    if ($csvFileList.isArray -eq $true)
    {
        p -message "It is an array"
    }
    else {
        p -message "it is not an array"
    }

    $numOfFiles = countFiles -fileList $csvFileList
    p -message "Number of files: $numOfFiles"

}

satya - 2/12/2020, 10:41:46 AM

Types in powershell


# **********************************************
 # It is useful to know what are the types of 
 # variables in powershell scripts
 # **********************************************
 function printTypeInformation ($inputobject)
 {
     Write-Host "printing type information for type: $($inputobject.GetType())"
     $typeDetails = $inputobject  | Get-Member
     $typeDetails
     $inputObject.GetType()
 }

 function printSimpleTypeInfo($inputObject)
 {
    if ($inputObject -eq $null)
    {
        p -message "The input object you passed is null."
        return
    }
    $typeObject = $inputObject.GetType()
    $typename = $typeObject.FullName
    $typeShortName = $typeObject.name

    p -message "Fullname of the type is: $typename"
    p -message "Short name is: $typeShortName"
    $typeObject
 }

 function getTypeFullname($inputObject)
 {
    if ($inputObject -eq $null)
    {
        p -message "The input object you passed is null."
        return $null
    }
    return $inputObject.GetType().FullName
 }

satya - 2/12/2020, 10:43:09 AM

Test types


function testSimpleTypeInfo()
{
    $s = "hello"
    printSimpleTypeInfo -inputObject $s

    #Don't do this
    printSimpleTypeInfo($s)
}

satya - 2/12/2020, 5:14:44 PM

Try and catch

Try and catch

satya - 2/12/2020, 5:16:05 PM

Terminating and nonterminating exceptions

Terminating and nonterminating exceptions

satya - 2/12/2020, 5:16:24 PM

Terminating and non terminating exceptions in powershell

Terminating and non terminating exceptions in powershell

Search for: Terminating and non terminating exceptions in powershell

satya - 2/12/2020, 5:16:54 PM

See if this works


$ErrorActionPreference = "Stop".

satya - 2/12/2020, 5:23:57 PM

$ErrorActionPreference powershell

$ErrorActionPreference powershell

Search for: $ErrorActionPreference powershell

satya - 2/19/2020, 12:05:02 PM

work with json files in powershell

work with json files in powershell

Search for: work with json files in powershell

satya - 2/21/2020, 12:03:45 PM

statistic functions in powershell

statistic functions in powershell

Search for: statistic functions in powershell

satya - 2/21/2020, 12:09:14 PM

Statistics module for powershell

Statistics module for powershell

satya - 2/21/2020, 12:10:29 PM

Measure-Object Powershell

Measure-Object Powershell

Search for: Measure-Object Powershell

satya - 2/21/2020, 12:10:45 PM

Docs on Measure-object

Docs on Measure-object

satya - 2/21/2020, 12:11:14 PM

Sorry that wasn't it. it is here

Sorry that wasn't it. it is here

satya - 2/22/2020, 5:08:11 PM

Here is the object output from a Measure-Object


Median            : 1647.65
Variance          : 191.604814814815
StandardDeviation : 13.8421390982324
Percentile10      : 1635.2
Percentile25      : 1642.2
Percentile75      : 1710.2
Percentile90      :
TukeysRange       : 102
Confidence95      : 0
Count             : 6
Average           : 1662.96666666667
Sum               : 9977.8
Maximum           : 1710.2
Minimum           : 1627.9
Property          : tag_value

satya - 2/23/2020, 11:59:08 AM

Here are some math functions employed to calculate average angles


#**************************************
    # Measure Average wind direction
    #**************************************
    #Get windspeed tagsg
    $windDirectionArray = $qtrArray | Where-Object {$_.tag_name -eq "YawDirection"} 
    p -message "Number of wind direction records in Q: $($windDirectionArray.Count)"

    $sin = 0
    $cos = 0

    foreach($item in $windDirectionArray)
    {
        [double]$angle = $item.tag_value
        p -message "angle: $angle"
        $sin += [Math]::Sin($angle * 0.0174533)
        $cos += [Math]::Cos($angle * 0.0174533)
    }

    p -message "$sin : $cos"
    $avgAngle = [Math]::Atan2($sin, $cos)
    $avgAngleInDegrees = $avgAngle * 57.2958
    $angle360 = calc360 -angle $avgAngleInDegrees

    p -message "The average angle is $avgAngle : $avgAngleInDegrees : $angle360"
}

function calc360($angle)
{
    $n = 360 + $angle;
    [int]$i = $n % 360
    return $i
}

satya - 2/23/2020, 12:00:07 PM

You will see output like this


angle: 310.899993896484
angle: 307.899993896484
angle: 325.200012207031
angle: 323.100006103516
angle: 319.899993896484
angle: 203
angle: 196.100006103516
angle: 307.299987792969
angle: 316.900024414063
angle: 316.5
angle: 313.5
-55.7941435452635 : 34.1923780225009

The average angle is 
in radians: -1.0209956848016 : 
in degrees: -58.4987645572553 : 
in positive degrees: 302

satya - 2/23/2020, 1:52:34 PM

A sample class


class PlantDataRecord
{
    [single]$generatedCapacity
    [single]$windSpeed
    [single]$windDirection

    [string]ToString(){
        return ("Power: {0}, WindSpeed {1}, Direction {2}" -f `
            $this.generatedCapacity, `
            $this.windSpeed, `
            $this.windDirection)
    }    
}

satya - 2/27/2020, 11:10:55 AM

How to automate powershell scripts through windows task scheduler

How to automate powershell scripts through windows task scheduler

Search for: How to automate powershell scripts through windows task scheduler

satya - 2/27/2020, 12:51:24 PM

Here is a good scheduler question where your tasks appear to disappear

Here is a good scheduler question where your tasks appear to disappear

satya - 2/27/2020, 12:52:54 PM

Key seem to be the "Library" option

Click on "Task Scheduler Library" and see the right hand side change

satya - 2/27/2020, 12:53:22 PM

How to redirect output in task scheduler in windows

How to redirect output in task scheduler in windows

Search for: How to redirect output in task scheduler in windows

satya - 2/27/2020, 12:54:38 PM

You can do the usual redirection


program >> somelog.txt

satya - 2/27/2020, 1:29:09 PM

Doesn't look like that simple with powershell

Doesn't look like that simple with powershell

satya - 2/27/2020, 3:25:31 PM

Apparently the answer is to create a batch file with a .bat extension

And have all the redirections controlled by that batch file.

satya - 2/28/2020, 7:47:56 PM

Import CSV with custom headers


function importForecastDataCSV($forecastDataFullFilename, $inPlantObject)
{
    $windForecastHeaderRow = 'datetime','forecast_generation_mw',....
    $solarForecastHeaderRow = 'datetime','forecast_generation_mw', ...
    [Plant]$plantObject = $inPlantObject

    $headerRow = $null

    if ($plantObject.typeName -eq "wind")
    {
        p -message "Processing using wind forecast header row"
        $headerRow = $windForecastHeaderRow
    }
    else {
        p -message "Processing using solar forecast header row"
        $headerRow = $solarForecastHeaderRow
    }
    [Object[]]$rows = Import-Csv -Path $forecastDataFullFilename -Header $headerRow

    #First row will have the header that came with the file
    #Remove it from the array
    $rows = $rows[1..($rows.Count - 1)]
    return $rows
}

satya - 2/29/2020, 6:36:54 PM

powershell regex

powershell regex

Search for: powershell regex

satya - 2/29/2020, 7:20:18 PM

Some examples


#Format: Forecaster_plant_HA_2020-02-22_10-00-00.csv
function validateHAforecastFilename($basefilename)
{
    $regex = "^[a-zA-Z0-9]+_[a-zA-Z0-9]+_HA_\d\d\d\d-\d\d-\d\d_\d\d-\d\d-\d\d.csv$"
    $result = $basefilename -match $regex
    return $result
}
function testReqex()
{
    $n1 = "ul_sidrap_HA_2020-02-28_10-05-00.csv"
    $n2 = "ul_sidrap_HA_2020-02-28_10-05-00.csvdd"
    $n3 = "ul_sidrap_HA_2020-02-28_10-05-00.json"
    $n4 = "_sidrap_HA_2020-02-28_100500.csv"
    $n5 = "ul_sidrap_HAT_2020-02-28_10-05-00.csv"
    $n6 = "ul_sidrap_DA_2020-02-28_10-05-00.csv"

    $n7 = "l_sidrap_HA_2020-02-28_10-05-00.csv"
    $n8 = "7ul_sidrap_HA_2020-02-28_10-05-00.csv"
    $n9 = "l999_sidrap_HA_2020-02-28_10-05-00.csv"

    validateHAforecastFilename -basefilename $n1 #true
    validateHAforecastFilename -basefilename $n2 #false
    validateHAforecastFilename -basefilename $n3 #false
    validateHAforecastFilename -basefilename $n4 #false
    validateHAforecastFilename -basefilename $n5 #false
    validateHAforecastFilename -basefilename $n6 #false

    validateHAforecastFilename -basefilename $n7 #true
    validateHAforecastFilename -basefilename $n8 #true
    validateHAforecastFilename -basefilename $n9 #true

}

satya - 2/29/2020, 7:21:42 PM

Regex from ss64.com

Regex from ss64.com

satya - 2/29/2020, 7:22:01 PM

online regex tester

online regex tester

satya - 2/29/2020, 7:22:40 PM

regex cheatsheet

regex cheatsheet

satya - 2/29/2020, 8:24:59 PM

These two would be similar


^[a-zA-Z0-9]+_[a-zA-Z0-9]+_HA_\d\d\d\d-\d\d-\d\d_\d\d-\d\d-\d\d.csv$

//using EXACT number of instances
^[a-zA-Z0-9]+_[a-zA-Z0-9]+_HA_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}.csv$

satya - 3/1/2020, 2:21:52 PM

Formatting a string


[string]ToString(){
        return ("Power: {0}, WindSpeed {1}, Direction {2}" -f `
            $this.generatedCapacity, `
            $this.windSpeed, `
            $this.windDirection)
    }

satya - 3/1/2020, 2:26:26 PM

Another way outside a class seems to be


"$($var1)_sometext_$($var2).csv"

satya - 3/4/2020, 4:43:31 PM

why is the task scheduler trying to launch multiple instances at the same time

why is the task scheduler trying to launch multiple instances at the same time

Search for: why is the task scheduler trying to launch multiple instances at the same time

satya - 3/10/2020, 5:23:39 PM

How to start a task when another task ends in windows task scheduler

How to start a task when another task ends in windows task scheduler

Search for: How to start a task when another task ends in windows task scheduler

satya - 3/10/2020, 5:33:21 PM

windows start command

windows start command

Search for: windows start command

satya - 3/10/2020, 5:36:02 PM

ss64 on start

ss64 on start

satya - 3/10/2020, 5:36:30 PM

Microsoft docs on start

Microsoft docs on start

satya - 3/10/2020, 5:50:53 PM

Nuances of running a powershell script

Nuances of running a powershell script

satya - 3/10/2020, 6:01:11 PM

how do I simulate wait in a powershell script?

how do I simulate wait in a powershell script?

Search for: how do I simulate wait in a powershell script?

satya - 3/10/2020, 6:01:38 PM

start-sleep docs

start-sleep docs

satya - 3/11/2020, 12:15:06 PM

Get-Error commandlet

Get-Error commandlet

Search for: Get-Error commandlet

satya - 3/11/2020, 12:15:15 PM

Docs Get-Error commandlet

Docs Get-Error commandlet

satya - 3/13/2020, 12:39:45 PM

Nature of ErrorRecord and Exception in Powershell


function testException()
{
    try { NonsenseString }
    catch {
        pe -message "error"
        [System.Management.Automation.ErrorRecord]$er = $_
        printTypeInformation -inputobject $er
        pe -message "Script stack trace is below"
        p -message $er.ScriptStackTrace
        p -message "Error details: $er.ErrorDetails"
    }
}
testException

satya - 3/13/2020, 2:52:11 PM

More ways to explore the ErrorRecord


function getExceptionMessage($errorRecord)
{
    if ($errorRecord -eq $null)
    {
        return "Sorry Error Record itself is null."
    }

    [System.Management.Automation.ErrorRecord]$er = $errorRecord
    if ($er.ErrorDetails -ne $null)
    {
        return $er.ErrorDetails.ToString()
    }

    #errordetails is null. See for exceptions
    if ($er.Exception -eq $null)
    {
        return "Sorry Error details is null and the Exception object is null in the error record"
    }

    #Exception exists
    $baseException = $er.Exception.GetBaseException()
    if ($baseException -ne $null)
    {
        return $baseException.Message
    }

    #base exception doesn't exist
    return $er.Exception.Message
}
function printErrorRecordDetails($errorRecord)
{
    if ($errorRecord -eq $null)
    {
        pe -message "A null error record is passed in to print its details"
        return
    }

    [System.Management.Automation.ErrorRecord]$er = $errorRecord
    if ($er.ErrorDetails -eq $null)
    {
        pe -message "ErrorDetail is null"
    }
    else {
        pe -message "Error Details follow"
        pe -message $er.ErrorDetails
    }
    if ($er.Exception -eq $null)
    {
        pe -message "Exception of the error record is null"
    }
    else {
        pe -message "Exception message: $er.Exception.Message"
    }

    # possibly [System.Management.Automation.RuntimeException]
    $baseException = $er.Exception.GetBaseException()
    printSimpleTypeInfo -inputObject $baseException

    pe -message "Script Stack trace for the error is below"
    pe -message $er.ScriptStackTrace

    if ($baseException -eq $null)
    {
        pe -message "Base exception is null"
    }
    else {
        pe -message "Base Exception message is: $($baseException.Message)"
        pd -message "Base Exception is: $baseException"
    }
}

satya - 3/14/2020, 1:19:18 PM

Trim for strings in powershell

Trim for strings in powershell

Search for: Trim for strings in powershell

satya - 3/14/2020, 1:19:39 PM

Trim function from SS64.com

Trim function from SS64.com

satya - 3/14/2020, 2:56:43 PM

How to figure out if a string is non empty in powershell

How to figure out if a string is non empty in powershell

Search for: How to figure out if a string is non empty in powershell

satya - 3/14/2020, 4:55:44 PM

One way to write isValid


function isValid($somestring)
{
    if ($somestring -eq $null)
    {
        return $false
    }
    
    if ($somestring -eq "")
    {
        return $false
    }

    $b = [String]::IsNullOrWhiteSpace($somestring)
    if ($b -eq $true)
    {
        #it is null or white space
        return $false
    }
    return $true
}

satya - 3/14/2020, 4:56:56 PM

Still a few flaws

How to verify the type of the input variable is a stirng?

what is the perf impact of calling a .net string call? Not sure? I haven't analyzed

Perhaps in the next version

satya - 3/16/2020, 10:51:43 AM

String and non string conversions for SQL


function getSQLStringForNonString($val)
{
    if ($val -eq $null)
    {
        return "null"
    }
    [String]$s = $val
    return $s
}
function getSQLStringForString($val)
{
    if ($val -eq $null)
    {
        return "null"
    }
    if ((isValid -somestring $val) -eq $false)
    {
        #Empty or null
        return "null"
    }
    #a valid string
    return escapeSingleQuotes -s $val
}


function test()
{

    #***********************************
    # Test for non strings
    #***********************************
    $i = 0
    $s = getSQLStringForNonString -val $i
    #0
    p -message "1$s"

    [single]$d = 3.46
    $s = getSQLStringForNonString -val $d
    #3.46
    p -message "2$s"

    $a = $null
    $s = getSQLStringForNonString -val $a
    #null
    p -message "3$s"


    #***********************************
    # Test for strings
    #***********************************
    $a = $null
    $s = getSQLStringForString -val $a
    #null
    p -message "4$s"

    $a = ""
    $s = getSQLStringForString -val $a
    #null
    p -message "5$s"

    $a = "   "
    $s = getSQLStringForString -val $a
    #null
    p -message "6$s"

    $a = " hello"
    $s = getSQLStringForString -val $a
    # hello
    p -message "7$s"

    $a = " hello'there "
    $s = getSQLStringForString -val $a
    # hello''there
    p -message "8$s"

}

satya - 3/16/2020, 1:42:05 PM

Few more functions


function convertStringToNumber($s)
{
    if ((isValid -somestring $s) -eq $false)
    {
        #invaliad string
        return $null
    }

    #valid string
    [int]$number = [int]$s
    return $number
}

function convertStringToFloat($s)
{
    if ((isValid -somestring $s) -eq $false)
    {
        #invaliad string
        return $null
    }

    #valid string
    [single]$numberFloat = [single]$s
    return $numberFloat
}

satya - 3/20/2020, 1:51:03 PM

Here is one way to run executables from powershell scripts


function invokeVSCode()
 {
     $vscodeWS = "C:\satya\data\code\vs-workspaces\pyspark-vs-workspace.code-workspace"
     code $vscodeWS
 }

Here "code" is a reference to vscode executable code.exe (or a batch file, as I am not sure).

satya - 3/20/2020, 1:55:20 PM

Invoke-Expression


#Say there is a function

function f1() {}

You can then do

[String]$functionName = "f1"

Then you can execute that function

Invoke-Expression -Command $functionName

Or

Invoke-Express -Command "f1"

satya - 3/20/2020, 1:56:11 PM

This is a better way to initialize, say hashtables


#
 # This is a better way to initialize
 # as this allows calling functions inside the initialization
 #
 # without this approach, the functions must be defined
 # prior to the initialization. 
 # That forces all dependent functions to be before as well
 #
 $script:dirDictionary = $null
 function init()
 {
    $script:dirDictionary = [ordered]@{
        vscode=createVSCodeCommand
        psutils = 'C:\satya\data\code\power-shell-scripts\individual\satya\git-util'
        home = 'c:\satya'
        pslearn = 'C:\satya\data\code\power-shell-scripts\individual\satya\learn'
        vsworkspaces = "C:\satya\data\code\vs-workspaces"
        shortcuts="C:\Users\satya\OneDrive\Desktop\shortcuts"
        test_func=createTestFunc
    }
}

satya - 3/20/2020, 1:57:43 PM

My Sample code for powershell: Learn Powershell Repo on Github

My Sample code for powershell: Learn Powershell Repo on Github

satya - 3/20/2020, 1:59:58 PM

Here is some sample code to automate your command line needs in windows

Here is some sample code to automate your command line needs in windows

satya - 3/20/2020, 2:30:14 PM

Those facilities include

1. Remember directories

2. Change directories easily

3. Remember and execute commands as if the commands are directories where changing a directory is just a special function :)

satya - 3/22/2020, 8:42:33 PM

is there a Pair class in powershell

is there a Pair class in powershell

Search for: is there a Pair class in powershell

satya - 3/22/2020, 8:58:23 PM

Going from a string to a date


function getDateForISOString($isoDateString)
{
    return [DateTime]::ParseExact($isoDateString, "yyyy-MM-dd HH:mm:ss",$null)
}

satya - 3/22/2020, 9:22:24 PM

Some more date code


function dbuTestDates()
{
    $dateS = Get-Date -Format s
    p -message "with -Format s: $dateS"
    #"2020-03-22T20:37:35"

    $dateS = Get-Date -Format "yyyy-MM-dd"
    p -message "with format yyyy-MM-dd: $dateS"
    #"2020-03-22"

    [DateTime]$today = Get-Date 
    $trow = $today.AddDays(1)
    p -message $today
    $todayMaxString = $trow.ToString("yyyy-MM-dd")
    p -message "Today midnight: $todayMaxString"

    [DateTime]$todayMaxDateTimeObj = convertDateOnlyStringToDateTime -dateOnlyString $todayMaxString
    p -message "Today midnight: $todayMaxDateTimeObj"

    $backDateTime = $todayMaxDateTimeObj.AddDays(-30)
    p -message "30days ago midnight: $backDateTime"

}

function convertDateOnlyStringToDateTime($dateOnlyString)
{
    $datetime = [DateTime]::ParseExact($dateOnlyString, "yyyy-MM-dd",$null)
    return $datetime
}
function getDurationFor($numberOfDaysBack)
{
    [DateTime]$today = Get-Date 
    $trow = $today.AddDays(1)
    $todayMaxString = $trow.ToString("yyyy-MM-dd")

    [DateTime]$todayMaxDateTimeObj = convertDateOnlyStringToDateTime -dateOnlyString $todayMaxString
    $backDateTime = $todayMaxDateTimeObj.AddDays(-$numberOfDaysBack)

    $duration = @{}
    $duration.fromDateString = getDateStringOnly -dateTimeObj $backDateTime
    $duration.toDateString = getDateStringOnly -dateTimeObj $todayMaxDateTimeObj
    return $duration
}
function getDateStringOnly($dateTimeObj)
{
    return $dateTimeObj.ToString("yyyy-MM-dd")
}

function testDuration()
{
    $d = getDurationFor -numberOfDaysBack 30
    p -message $d.fromDateString
    p -message $d.toDateString
}

satya - 3/26/2020, 4:40:20 PM

Compare-object article

Compare-object article

satya - 3/26/2020, 4:47:25 PM

intersection of datasets in powershell

intersection of datasets in powershell

Search for: intersection of datasets in powershell

satya - 3/26/2020, 4:56:13 PM

Compare-Object

Compare-Object

Search for: Compare-Object

satya - 3/26/2020, 4:57:45 PM

Compare-object at SS64

Compare-object at SS64

satya - 3/26/2020, 4:58:42 PM

Docs on compare-object

Docs on compare-object

satya - 3/26/2020, 10:22:26 PM

Some magic with foreach


function whatChanged($since)
{
    $codeDir = "C:\satya\data\code\jakarta\general-repo"
    changeDirectory -toDir $codeDir
    $filenames = Get-ChildItem *.* -Recurse -File | `
        Where-Object {(whatchangedFileFilter -since $since -fileObj $_)}

    #$filenames | Format-Table -Property FullName

    $filenames | ForEach-Object {replaceRoot -fileObj $_ -root $codeDir} 

}

function replaceRoot($fileObj, $root)
{
    [System.IO.FileInfo]$f = $fileObj
    [String]$fullName = $f.FullName
    return $fullName.Replace($root, "")
}
function whatchangedFileFilter($fileObj, $since)
{
    [System.IO.FileInfo]$f = $fileObj
    if (($f.Extension -in ".txt", ".csv", ".json", ".bak", ".xlsx", ".xml") -eq $true)
    {
        return $false
    }
    #If the file is more recent
    $past = getDateInThePastFor($since)
    if ($f.LastWriteTime -gt $past)
    {
        return $true
    }
    return $false
}

satya - 3/27/2020, 9:16:11 AM

how can I function in powershell receive a piped input

how can I function in powershell receive a piped input

Search for: how can I function in powershell receive a piped input

satya - 3/30/2020, 3:07:36 PM

Operators in powershell

Operators in powershell

satya - 3/30/2020, 3:07:57 PM

Call operator in powershell

Call operator in powershell

Search for: Call operator in powershell

satya - 4/1/2020, 11:23:39 AM

working with file lists is tricky


function getStagedCSVFiles()
{
    hp("Listing staged csv files")
    $csvFileList = listHourAheadCSVFiles -directory $stagingDirectoryPath
    #printTypeInformation -inputobject $csvFileList
    return $csvFileList
}

function listHourAheadCSVFiles($directory)
{
    $fileList = Get-ChildItem -path "$directory/*_XYZ_*.csv" 
    return $fileList
}

function countFiles($fileList)
{
    if ($fileList -eq $null)
    {
        return 0
    }
    $fullname = getTypeFullname -inputObject $fileList
    if ($fullname -eq 'System.Object[]')
    {
        [System.Object[]]$a = $fileList
        return $a.Count
    }
    if ($fullname -eq "System.IO.FileInfo")
    {
        return 1
    }
    return $null
}


function getTypeFullname($inputObject)
 {
    if ($inputObject -eq $null)
    {
        p -message "The input object you passed is null."
        return $null
    }
    return $inputObject.GetType().FullName
}

$csvFileList = getStagedCSVFiles
$numOfFiles = countFiles -fileList $csvFileList

if ($numOfFiles -eq 0)
{
}

function printFileList($csvFileList)
{
    foreach($file in $csvFileList)
    {
        [System.IO.FileInfo]$file1 = $file
        p -message $file1.FullName
    }
}

satya - 4/1/2020, 9:26:01 PM

Formatting numbers is documented here

Formatting numbers is documented here

satya - 4/1/2020, 10:22:36 PM

Better way to deal with arrays for efficiency


class QuarterArrays
{
    [System.Collections.ArrayList]$firstQtr = [System.Collections.ArrayList]@()
    [System.Collections.ArrayList]$secondQtr = [System.Collections.ArrayList]@()
    [System.Collections.ArrayList]$thirdQtr = [System.Collections.ArrayList]@()
    [System.Collections.ArrayList]$fourthQtr = [System.Collections.ArrayList]@()

    [void]sinkRow($dataItem)
    {
        $time = $dataItem.timestamp
        $min = getMinutePortion1 -time $time
        if (($min -ge 0) -and ($min -lt 14))
        {
            $this.firstQtr.Add($dataItem)
        }
        elseif (($min -ge 15) -and ($min -lt 30)) {
            $this.secondQtr.Add($dataItem)
        }
        elseif (($min -ge 30) -and ($min -lt 45)) {
            $this.thirdQtr.Add($dataItem)
        }
        elseif (($min -ge 45) -and ($min -le 59)) {
            $this.fourthQtr.Add($dataItem)
        }
    }
    [void]reportNumbers()
    {
        hp -message "Reporting numbers from quarter arrrays"
        p -message "1stQtr: $($this.firstQtr.Count)"
        p -message "2 Qtr: $($this.secondQtr.Count)"
        p -message "3 stQtr: $($this.thirdQtr.Count)"
        p -message " 4stQtr: $($this.fourthQtr.Count)"

    }
}

satya - 4/4/2020, 10:53:48 PM

Here is an example of a param block


param (
    #Forecaster id
    $paramForecasterId,

    $paramForecasterName,

    #Base directory for the stage and archive directories
    $paramForecasterBaseDir,

    $paramMaxFilesToProcess,

    $paramRunLocal = $true
)

satya - 4/11/2020, 11:51:58 AM

one way to include other scripts


#Common db utilities
."$libScriptDir\common-dbutils.ps1"

satya - 4/17/2020, 10:42:16 AM

How do you filter filenames on command line in powershell

How do you filter filenames on command line in powershell

Search for: How do you filter filenames on command line in powershell

satya - 4/17/2020, 10:45:31 AM

You can do this


dir | where-object -property name -like "*.*"

satya - 4/17/2020, 10:46:01 AM

Or


dir | where {($_.name -like "*.*")}

satya - 4/17/2020, 10:53:44 AM

You could have done that


#as

dir *.*

#but the approach is valuable when

#Tell me on a file object 
#is there a property like "len"

dir | get-member | where -property name -like *len*

satya - 4/18/2020, 10:35:55 AM

Remove-item docs

Remove-item docs

Search for: Remove-item docs

satya - 4/18/2020, 10:36:17 AM

docs for Remove-item

docs for Remove-item

satya - 4/18/2020, 10:46:02 AM

write-host considered harmful: article

write-host considered harmful: article

satya - 4/18/2020, 10:46:46 AM

book excerpt: understanding ps pipeline

book excerpt: understanding ps pipeline

satya - 4/18/2020, 10:51:04 AM

Another code sample


function showAndDelete($jsonDi)
{
    [DirInfo]$di = $jsonDi
    hp -message "Showing top 10 files... "
    #This line avoids conflict between write-host and the pipeline output
    #uses write-host via function "p" below instead of printing to the pipeline that is the default
    
    $di.oldFileList | Select-Object -First 10 | ForEach-Object {p -message $_.fullname}
    
    $ans = consoleUtils.readHostWithDefault -prompt "Shall I delete...(y/n):" -default "n"
    if ($ans -eq "n")
    {
        p -message "returning."
        return
    }
    pt -message "Going to delete all the .json files now"
    $di.oldFileList | ForEach-Object {Remove-Item -path $_}
    pt -message "Done deleting .json files"
}

satya - 4/18/2020, 1:17:15 PM

foreach-object docs

foreach-object docs

satya - 4/18/2020, 1:33:08 PM

You can use ; to sep statements. and return is possible see below


ForEach-Object {$_.size = [int]($_.size/1000000); $_}

satya - 4/18/2020, 2:07:23 PM

Format-table docs

Format-table docs

satya - 4/18/2020, 2:07:34 PM

it has an alignment directive

it has an alignment directive

satya - 4/18/2020, 2:45:21 PM

Many ways to spec a property string to format table


$propString = @("dirName", "numOfFiles", "size", "oldFiles", "age", "oldFileSize", "netSize")

$sizeProp = @{
    name="size"
    expression={$_.size}
    alignment="right"
}

$propString2 = @("dirName", 
    "numOfFiles", 
    $sizeProp, 
    "oldFiles", 
    "age", 
    "oldFileSize", 
    "netSize")

satya - 4/18/2020, 11:35:16 PM

powershell.exe -file option

powershell.exe -file option

satya - 4/18/2020, 11:38:02 PM

You can do this


powershell.exe -File ./something.ps1 -arg1 blah -arg2 abc

satya - 4/18/2020, 11:46:18 PM

all the following are good


./a.ps1 "arg1" arg2 "arg3 is a longone"

or

./a.ps1 arg1 arg2 arg3

or

./a.ps1 -arg1 arg1 -arg2 arg2 -arg3 "arg3 is a longone"

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

quirks of a hashtable printing


$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:44:39 AM

You can do this to a hashtable


#Get your type right
[System.Collections.Hashtable]$newargs = $script:myargs

#you can vscode to prompt for methods
$newArgs.add("paramRunMode", "auto")

#print it
$newargs

satya - 4/19/2020, 11:07:56 AM

Redirect example


."$scriptDir\$realScriptName"  @myargs 6>&1 > $logfilename

satya - 4/26/2020, 1:05:26 PM

Powershell script tips from Microsoft

Powershell script tips from Microsoft

satya - 4/27/2020, 7:22:49 PM

Intermediate uncaptured values can create havoc


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 - 4/28/2020, 10:27:08 AM

How to validate function arguments for null in powershell

How to validate function arguments for null in powershell

Search for: How to validate function arguments for null in powershell

satya - 4/28/2020, 10:40:21 AM

Syntax for parameter validation is verbose for simple run of the mill functions

Syntax for parameter validation is verbose for simple run of the mill functions

satya - 4/28/2020, 10:45:34 AM

How to test for non nulls in powershell

How to test for non nulls in powershell

Search for: How to test for non nulls in powershell

satya - 4/28/2020, 11:18:42 AM

I prefer a better syntax like this instead


function fileUtil.getGeneralTimeStampedJustFilename($prefix, $datetimeObj, $ext)
{
    vutils.notnull $prefix $datetimeObj $ext
    vutils.notEmpty $prefix $ext
....
....
rest of the code
....

satya - 4/29/2020, 12:00:59 PM

How do I export a CSV?

1. Define an object

2. Get an array of those objects

3. Use export-csv commandlet with the options you need to export to a csv file

satya - 4/30/2020, 9:30:26 AM

Get a random date


function datetime.getRandom()
{
    $hour = Get-Random -Maximum 23 -Minimum 0
    $min = Get-Random -Maximum 59 -Minimum 0
    $sec = Get-Random -Maximum 59 -Minimum 0
    $date = Get-Date
    $d2 = $date.Date
    $d2 = $d2.AddHours($hour)
    $d2 = $d2.AddMinutes($min)
    $d2 = $d2.AddSeconds($sec)
    return $d2
}

satya - 4/30/2020, 10:19:58 AM

Somemore date time code


function datetime.sampleQtr($datetimeObj)
{
    [DateTime]$d = $datetimeObj
    $date = $d.Date
    $hour = $d.Hour
    $min = $d.Minute
    $qtr = $null
    switch ($min) {
        {$_ -ge 0 -and $_ -lt 15} {$qtr = 0;break }
        {$_ -ge 15 -and $_ -lt 30} {$qtr = 15;break }
        {$_ -ge 30 -and $_ -lt 45} {$qtr = 30;break }
        {$_ -ge 45 -and $_ -lt 60} {$qtr = 45;break }
    }
    if ($qtr -eq $null) {throw "Invalid. quarter cannot be null"}
    $nd = $date.AddHours($hour)
    $nd = $nd.AddMinutes($qtr)
    return $nd
}

satya - 4/30/2020, 10:23:39 AM

ss65: Nature of swtich

ss65: Nature of swtich

satya - 4/30/2020, 10:24:10 AM

docs on switch at microsoft

docs on switch at microsoft

satya - 4/30/2020, 4:19:30 PM

how to declare function return types

how to declare function return types

Search for: how to declare function return types

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

An example


function Get-Time
{
  [OutputType([DateTime])]
  Param (
    [parameter(Mandatory=$true)]
    [Datetime]$DateTime
  )

  $DateTime.ToShortTimeString()
}

satya - 4/30/2020, 5:03:23 PM

Curious concept: ouput type attribute docs

Curious concept: ouput type attribute docs

satya - 4/30/2020, 5:51:00 PM

A useful thing I hope to use: Get-PsCallstack

A useful thing I hope to use: Get-PsCallstack

satya - 5/1/2020, 9:08:48 AM

You can print call stack this way


function printCallStack()
{
    hp -message "Pringing call stack"
    $a = Get-PSCallStack | ForEach-Object {$_.Command + "," + $_.Location}
    foreach($item in $a)
    {
        p -message $item
    }
}

satya - 5/2/2020, 11:10:47 AM

Nature of custompsobject


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : Equals
MemberType : Method
Definition : bool Equals(System.Object obj)


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : GetHashCode
MemberType : Method
Definition : int GetHashCode()


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : GetType
MemberType : Method
Definition : type GetType()


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : ToString
MemberType : Method
Definition : string ToString()


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : root
MemberType : NoteProperty
Definition : string root=Sensor-1082


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : tag_name
MemberType : NoteProperty
Definition : string tag_name=T_MOD


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : tag_value
MemberType : NoteProperty
Definition : string tag_value=24.42698


TypeName   : Selected.System.Management.Automation.PSCustomObject
Name       : timestamp
MemberType : NoteProperty
Definition : string timestamp=2020-05-01 20:45:00

True     False    PSCustomObject                           System.Object

satya - 5/2/2020, 11:20:28 AM

Add-Member has an explanation of NoteProperties

Add-Member has an explanation of NoteProperties

satya - 5/3/2020, 2:39:51 PM

Documentation of Export-csv

Documentation of Export-csv

satya - 5/7/2020, 11:27:40 AM

Controlling format-table. Annoying

Controlling format-table. Annoying

satya - 5/7/2020, 11:27:56 AM

Out-String commandlet

Out-String commandlet

Search for: Out-String commandlet

satya - 5/7/2020, 11:30:49 AM

Out-String useful docs

Out-String useful docs

satya - 5/15/2020, 4:36:35 PM

Format-Table with Out-String


Some-list | Format-Table -Autosize | out-string -width 100

satya - 5/15/2020, 5:09:42 PM

Sorting by property


$dlist = @($d1, $d2, $d3, $d4)
$dSortedList = $dList | Sort-Object -Property start

satya - 5/17/2020, 9:13:47 AM

sequence generator commandlet in powershell

sequence generator commandlet in powershell

Search for: sequence generator commandlet in powershell

satya - 5/17/2020, 9:33:53 AM

Very early attempt at implementing sequences with closures


function utils.number.getSeqGenerator($increment=1)
{
    $count=0;
    {
        $script:count += $increment
        return $count
    }.GetNewClosure()
}

$script:utils_number_SeqGenerator_next = utils.number.getSeqGenerator

function utils.number.getNextSeq()
{
    $n  = &$script:utils_number_SeqGenerator_next
    return $n
}

function testSeq()
{
    $n = utils.number.getNextSeq
    p -message $n
    $n = utils.number.getNextSeq
    p -message $n
    $n = utils.number.getNextSeq
    p -message $n
    $n = utils.number.getNextSeq
    p -message $n
}

satya - 5/17/2020, 9:40:47 AM

I wonder if a class is not better instead, as that will give resets and more methods

I wonder if a class is not better instead, as that will give resets and more methods

satya - 5/23/2020, 6:20:47 PM

How to remove files older than a certain date in powershell


dir | Where-Object -Property LastWriteTime -LT yyyy-mm-dd | Remove-item

satya - 5/24/2020, 10:12:29 PM

inheritance in powershell

inheritance in powershell

Search for: inheritance in powershell

satya - 5/24/2020, 10:22:52 PM

Example


class classDuration
{
    [DateTime]$start
    [DateTime]$end

    [string]ToString(){
        return ("start: {0}, End {1}" -f `
            $this.start, `
            $this.end)
    }   
}#end of class

class classDurationDateStrings : classDuration {
    [String]startDateString(){
        return $this.start.ToString("yyyy-MM-dd")
    }

    [String]endDateString(){
        return $this.end.ToString("yyyy-MM-dd")
    }
    [string]ToString(){
        return ("start: {0}, End {1}" -f `
            $this.startDateString(), `
            $this.endDateString())
    }   
}

satya - 5/24/2020, 10:45:00 PM

Slightly better class


class classDurationDateStrings : classDuration {

    classDurationDateStrings(){}
    classDurationDateStrings([classDuration]$d)
    {
        $this.start = $d.start
        $this.end = $d.end
    }

    [String]startDateString(){
        return $this.start.ToString("yyyy-MM-dd")
    }

    [String]endDateString(){
        return $this.end.ToString("yyyy-MM-dd")
    }
    [string]ToString(){
        return ("start: {0}, End {1}" -f `
            $this.startDateString(), `
            $this.endDateString())
    }   
}

satya - 5/24/2020, 10:45:52 PM

This one

1. provides a way to convert from base to derived

2. Also keeps the base class initialization undisturbed with an empty constructor so both initializations are valid.

satya - 5/24/2020, 11:14:05 PM

One way to unify write-host and the stdout


function collectionUtils.printArray3($a, $message)
{
    p -message $message
    if ($a -eq $null)
    {
        "The data array is null"
        return
    }
    $c = $a.Count
    if ($c -eq 0)
    {
        "The data array is empty"
        return
    }
    $msg = $a | Format-Table | Out-String
    p -message $msg

}

satya - 5/25/2020, 2:12:18 PM

Result set row type


System.data.DataRow

satya - 5/25/2020, 2:14:41 PM

Extracting columns from a resultset


function getTimeArray($rs)
{
    #This will create a set of objects
    #where each object has one property named "f_date_time"
    #so that is an array of hashtables or objects
    $dtArray = $rs | Select-Object -Property f_date_time

    #This is a collection, on the otherhand, of date time array
    $dtArray = $rs | ForEach-Object {return $_.f_date_time}

    return $dtArray
}

satya - 5/28/2020, 12:37:15 PM

This is a useful method


function vutils.default($param, $value, $default)
{
    if ($param -eq $null)
    {
        return $default
    }
    return $value
}

satya - 5/28/2020, 12:39:05 PM

That was wrong


function vutils.default($param, $default)
{
    if ($param -eq $null)
    {
        return $default
    }
    return $param
}

satya - 5/28/2020, 12:41:18 PM

Then you can do this


function fcDataReportFor($plant, $forecaster, $frequency, $howFarBackInDays)
{
    vutils.notnull $plant $forecaster
    $lFrequency = vutils.default -param $frequency -default 15
    $lPast = vutils.default -param $howFarBackInDays -default 30

satya - 5/28/2020, 9:09:21 PM

Playing with param blocks. Start here


param (
    $paramRunMode = "runReport"
)

satya - 5/28/2020, 9:09:45 PM

It can take on the following options


$optionHelp = "help"
$optionRunReport = "runReport"
$optionCleanupManual = "cleanupManual"
$optionCleanupAuto = "cleanupAuto"

$optionArray = @(
    $optionHelp,
    $optionRunReport,
    $optionCleanupManual,
    $optionCleanupAuto
)

satya - 5/28/2020, 9:10:48 PM

Then you can use those two this way


function driverMainProc()
{
    if ($paramRunMode -eq $null)
    {
        p -message "No Parameters passed"
        p -message "Running Run Report as the default"
        p -message "use string 'help' as an option if you need help"
        runReport
        return
    }
    
    if ($paramRunMode -eq $optionHelp)
    {
        promptHelp
        return
    }

    if ($paramRunMode -eq $optionRunReport)
    {
        runReport
        return
    }
    if ($paramRunMode -eq $optionCleanupManual)
    {
        runManually
        return
    }
    if ($paramRunMode -eq $optionCleanupAuto)
    {
        runAuto
        return
    }
    #none
    p -message "Unrecognized string as an option"
    promptHelp
}

driverMainProc

satya - 5/28/2020, 9:14:37 PM

promptHelp can do this then


function promptHelp()
{
    hp -message "Here are the params"

    $optionArray
}

satya - 5/28/2020, 9:48:43 PM

samething with a switch and default


function driverMainProc1()
{
    init
    switch ($paramRunMode) 
    {
        $null {
            p -message "No Parameters passed"
            p -message "Running Report just for data"
            p -message "use string 'help' as an option if you need help"
            runReport
            break
        }
        $optionHelp
        {
            promptHelp
            break
        }
        $optionJustData
        {
            runReport
            break
        }
        $optionGaps
        {
            runReport
            break
        }
        default 
        {
            p -message "Unrecognized string as an option"
            promptHelp
            break
        }
    }#end of switch
}

satya - 5/29/2020, 7:57:45 PM

A fancy with switch and map


$x = "ha"
$y = "dddd"
$tableName = switch ($y)
{
    "ha" { "a" }
    "da" { "b" }
    default {"x"}
}

p -message $tableName

function map($var, $op1, $op1Value, $op2, $op2Value, $defaultValue)
{
    $r = switch ($var)
    {
        $op1 { $op1Value }
        $op2 { $op2Value }
        default {$defaultValue}
    }
    return $r
}

$tableName = map -var $x `
    -op1 "ha" -op1Value "a" `
    -op2 "da" -op2Value "b" `
    -defaultValue "x"

p -message $tableName

satya - 5/29/2020, 8:06:30 PM

Nice I can do this


vutils.notnull $plant $forecaster $duration $forecastType

    $daTableName = "t_vre_da_forecast_data"
    $haTableName = "t_vre_ha_forecast_data"

    $tableName = vutils.map -var $forecastType `
        -op1 "ha" $haTableName `
        -op2 "da" $daTableName `
        -defaultValue $null
        
    vutils.notnull $tableName

satya - 6/3/2020, 9:15:22 PM

Using Regex with Powershell: Kevin

Using Regex with Powershell: Kevin

satya - 6/3/2020, 9:16:05 PM

Powershellexplained.com

Powershellexplained.com

satya - 6/3/2020, 11:25:29 PM

Putting it all together: String tokenizing using regex matching groups


function getDateTimeFromFilenameUsingRegEx($filename, $expr)
{
    #returns a boolean
    $reply = $filename -match $expr

    $date = $Matches.date
    $month = $Matches.month
    $year = $Matches.year

    #Make sure the expression has correctly located year, month, and day
    vutils.notnull $date $month $year

    $datetime = [DateTime]::new($year, $month, $date)
    return $datetime
}

function test()
{
    $filename = "SomeFilePrefix12-05-2020"
    $expr = "SomeFilePrefix(?<date>\d\d)-(?<month>\d\d)-(?<year>\d\d\d\d)"    

    $dt = getDateTimeFromFilenameUsingRegEx -filename $filename -expr $expr
    $s = convertToISOTime2 -datetime $dt

    #prints 2020-05-12 00:00:00
    p -message $s
}

satya - 6/4/2020, 9:37:19 AM

How can I see a list of function names in a powershell script file in vscode

How can I see a list of function names in a powershell script file in vscode

Search for: How can I see a list of function names in a powershell script file in vscode

satya - 6/5/2020, 11:25:36 AM

Sort-Object with comparator powershell

Sort-Object with comparator powershell

Search for: Sort-Object with comparator powershell

satya - 6/5/2020, 11:27:29 AM

Sort-Object docs

Sort-Object docs

satya - 6/5/2020, 11:43:23 AM

Sorting using a custom function


$someFileList = Get-ChildItem

$someFileList | Sort-Object -Property @{ 
      Expression = (someFunc -arg1 $_); 
      Descending = $true }, 

     #sub expression
     @{ Expression = 'Name'; Ascending = $true }

function someFunc($arg1) {}

satya - 6/7/2020, 1:07:55 PM

Precision of an NTFS is 100 nanoseconds. So be aware of storing last file times!!

Precision of an NTFS is 100 nanoseconds. So be aware of storing last file times!!

satya - 6/7/2020, 1:08:14 PM

Understand file times

Understand file times

satya - 6/7/2020, 1:53:44 PM

datetime milliseconds and microseconds is explained here

datetime milliseconds and microseconds is explained here

satya - 6/7/2020, 1:55:16 PM

DateTime class documentation

DateTime class documentation

satya - 6/7/2020, 1:57:31 PM

An example of fraction of milliseconds

Notice the precision of milliseconds: 7fs


string dateFormat = "MM/dd/yyyy hh:mm:ss.fffffff";
DateTime date1 = new DateTime(2010, 9, 8, 16, 0, 0);

satya - 6/7/2020, 2:03:19 PM

How are strings formatted in .Net: Composite formatting

How are strings formatted in .Net: Composite formatting

satya - 6/7/2020, 2:03:50 PM

Try that again

Try that again

satya - 6/7/2020, 2:08:20 PM

Formatting numbers

Formatting numbers

satya - 6/7/2020, 2:10:18 PM

This code segment is useful from MS


string dateFormat = "MM/dd/yyyy hh:mm:ss.fffffff";
DateTime date1 = new DateTime(2010, 9, 8, 16, 0, 0);
Console.WriteLine("Original date: {0} ({1:N0} ticks)\n",
                  date1.ToString(dateFormat), date1.Ticks);

DateTime date2 = date1.AddMilliseconds(1);
Console.WriteLine("Second date:   {0} ({1:N0} ticks)",
                  date2.ToString(dateFormat), date2.Ticks);
Console.WriteLine("Difference between dates: {0} ({1:N0} ticks)\n",
                  date2 - date1, date2.Ticks - date1.Ticks);

DateTime date3 = date1.AddMilliseconds(1.5);
Console.WriteLine("Third date:    {0} ({1:N0} ticks)",
                  date3.ToString(dateFormat), date3.Ticks);
Console.WriteLine("Difference between dates: {0} ({1:N0} ticks)",
                  date3 - date1, date3.Ticks - date1.Ticks);
// The example displays the following output:
//    Original date: 09/08/2010 04:00:00.0000000 (634,195,584,000,000,000 ticks)
//
//    Second date:   09/08/2010 04:00:00.0010000 (634,195,584,000,010,000 ticks)
//    Difference between dates: 00:00:00.0010000 (10,000 ticks)
//
//    Third date:    09/08/2010 04:00:00.0020000 (634,195,584,000,020,000 ticks)
//    Difference between dates: 00:00:00.0020000 (20,000 ticks)

satya - 7/26/2020, 12:27:49 PM

import xml file in powershell

import xml file in powershell

Search for: import xml file in powershell

satya - 7/26/2020, 12:32:22 PM

Few hints


# From CSV
Import-CSV $filename

# From json
$s = Get-Content $jsonfile | ConvertFrom-Json

satya - 7/26/2020, 12:41:16 PM

There is no convert from or importing an XML file I found

There is no convert from or importing an XML file I found

satya - 7/26/2020, 12:41:33 PM

I did see Select-XML however here

I did see Select-XML however here

satya - 7/26/2020, 12:59:34 PM

XPath examples from MS

XPath examples from MS

satya - 7/26/2020, 6:05:10 PM

Strangeness of Select-XML is very quietly documented here

Strangeness of Select-XML is very quietly documented here

satya - 7/26/2020, 6:08:31 PM

Introducing new line chars in powershell strings


"Name: {0}, `nFreq {1}, `nstart {2}"

satya - 7/26/2020, 11:05:01 PM

Select-string grep like docs

Select-string grep like docs

satya - 7/30/2020, 10:21:03 AM

Sample code writing to CSV


function writeToCSV($dir, $taskObjList)
{
    $filepath = $dir + "\exported-tasks.csv"
    p -message "Going to write a csv file: $filepath"
    $r = $taskObjList | Export-Csv -Path $filepath -NoTypeInformation
    p -message "Finished writing a csv file: $filepath"
}

satya - 7/30/2020, 10:27:26 AM

You can start with an object like this


class TaskObject
{
    $name
    $start_dt
    $freq
    $script
    $status
    [string]$cmd #if needed, use type
}

satya - 7/30/2020, 10:29:50 AM

You can then do this


#Get an array of TaskObjects
$taskObjArray = getSomeFunction()

#pick the fields you like

$newTaskObjArray = $taskObjArray | Select-Object -Property name, freq

#Write those to a csv file

#dir = "c:\some-dir"

#Call the write to csv function above
writeToCSV -dir $dir -taskObjList $na

satya - 7/30/2020, 10:31:28 AM

Export CSV docs

Export CSV docs

satya - 7/30/2020, 10:32:01 AM

How do I export a CSV?

1. Define an object

2. Get an array of those objects

3. Use export-csv commandlet with the options you need to export to a csv file

satya - 7/30/2020, 10:54:37 AM

Powershell csv commandlets

Import-csv:Search On Web

ConvertTo-Csv:Search On Web

Export-CSV:Search On Web

ConvertFrom-CSV:Search On Web

satya - 9/12/2020, 12:13:59 PM

Powershell and REST

Powershell and REST

satya - 9/18/2020, 6:37:06 PM

A simple template for including scripts and params


<#
#*********************************************
# A starting file for writing scripts
#********************************************
#>

param (
    $paramOutputFilename
)

#*********************************************
#  Execute Common libraries: Include this one at the top
#********************************************
function getScriptDir() {
    $script_path    =  $myinvocation.PSCommandPath
    $script_folder  = split-path $script_path -parent
    $script_name    = split-path $script_path -leaf    
    return $script_folder
}

$libScriptDir = getScriptDir

if ($psutilsIncluded -eq $null)
{
    ."$libScriptDir\psutils.ps1"
    ."$libScriptDir\common-utils.ps1"
}

#*********************************************
# End Execute Common libraries
#********************************************

$realScriptName="show-plant-data-files.ps1"

function printHelp()
{
    p -message "Specify an output filename as the first argument"
    return
}
function mainproc()
{
    mhp -message "Running report to show received plant files"
    if ((isValid -somestring $paramOutputFilename) -eq $false)
    {
        printHelp
        return
    }
    p -message "Going to write output to: $paramOutputFilename"

    p -message "Going to run script below"
    p -message "$libScriptDir\$realScriptName"

    ."$libScriptDir\$realScriptName" 6>&1 > $paramOutputFilename

    p -message "Finished running the script."
}

#run the stuff
mainproc
p -message ""

satya - 9/19/2020, 12:23:17 PM

powershell mandatory params

powershell mandatory params

Search for: powershell mandatory params

satya - 9/23/2020, 10:16:08 PM

interfaces and inheritance in powershell

interfaces and inheritance in powershell

Search for: interfaces and inheritance in powershell

satya - 9/11/2022, 12:34:05 PM

Multiline strings in powershell

Multiline strings in powershell

Search for: Multiline strings in powershell

satya - 9/11/2022, 12:36:54 PM

This is mentioned above as well. Look for @ for line and string continuation


$somestring = @"
   line1
  line2
line3
This termination must be the first 2 characters
"@

satya - 9/11/2022, 12:42:03 PM

Another example


function sayAbout()
{
    $aboutMessage = 
@"
A program to generate a private key
Inputs: Password, filename
Outputs: Writes the filename to the local directory
"@
    hp "About: Private Key Generator Script"
    p $aboutMessage
}

satya - 9/11/2022, 9:50:59 PM

exit process in powershell

exit process in powershell

Search for: exit process in powershell