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
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
satya - 2/2/2020, 4:29:33 PM
line continuation in powershell
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: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
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
satya - 2/5/2020, 2:39:19 PM
is T optional in ISO date formats?
is T optional in ISO date formats?
satya - 2/5/2020, 6:06:29 PM
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
satya - 2/5/2020, 6:08:07 PM
powershell class definitions
powershell class definitions
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
satya - 2/5/2020, 6:49:35 PM
t-sql sample stored procedures
t-sql sample stored procedures
satya - 2/6/2020, 12:36:38 AM
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
satya - 2/6/2020, 12:41:10 AM
Invoke-SQLCommand powershell
Invoke-SQLCommand powershell
satya - 2/7/2020, 10:33:56 AM
strangeness and rules of braces in powershell
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
satya - 2/7/2020, 10:52:40 AM
PSCustom Object to a typed object in powershell
PSCustom Object to a typed object in powershell
satya - 2/7/2020, 11:11:19 AM
Add-Type commandlet
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
annonymous - 2/7/2020, 11:42:32 AM
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
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: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
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
satya - 2/8/2020, 5:39:54 PM
data types for import-csv commandlet
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
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
satya - 2/9/2020, 4:42:39 PM
about param powershell
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
satya - 2/9/2020, 5:09:08 PM
what is $PSScriptRoot
what is $PSScriptRoot
satya - 2/9/2020, 5:10:07 PM
Invoke-Expression Commandlet
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
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
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
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
satya - 2/10/2020, 10:42:31 AM
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
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
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
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:16:05 PM
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
satya - 2/19/2020, 12:05:02 PM
work with json files in powershell
work with json files in powershell
satya - 2/21/2020, 12:03:45 PM
statistic functions in powershell
statistic functions in powershell
satya - 2/21/2020, 12:10:29 PM
Measure-Object Powershell
Measure-Object Powershell
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, 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, 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
satya - 3/10/2020, 5:50:53 PM
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?
satya - 3/11/2020, 12:15:06 PM
Get-Error commandlet
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
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
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:47:25 PM
intersection of datasets in powershell
intersection of datasets in powershell
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:57 PM
Call operator in powershell
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
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:46:02 AM
write-host considered harmful: article
satya - 4/18/2020, 10:46:46 AM
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: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: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: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
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
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, 4:19:30 PM
how to declare function return types
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
satya - 4/30/2020, 5:51:00 PM
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
satya - 5/7/2020, 11:27:56 AM
Out-String commandlet
Out-String commandlet
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
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
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, 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
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:53:44 PM
datetime milliseconds and microseconds is explained here
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
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
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, 6:05:10 PM
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/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: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/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
satya - 9/23/2020, 10:16:08 PM
interfaces and inheritance in powershell
interfaces and inheritance in powershell
satya - 9/11/2022, 12:34:05 PM
Multiline strings in powershell
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