Skip to content

Instantly share code, notes, and snippets.

@ninmonkey
Last active May 29, 2022 18:05
Show Gist options
  • Select an option

  • Save ninmonkey/20bbe055136262944ddbcf461d65b751 to your computer and use it in GitHub Desktop.

Select an option

Save ninmonkey/20bbe055136262944ddbcf461d65b751 to your computer and use it in GitHub Desktop.
Piping-Output-Powershell.ps1.md

? Means filter, ! means Assert.

? Style Can Silently Filter, Dropping Failed objects like -ea Ignore

$names = 'foo', '   ', 'bar'

$names
| Len # prints 3

$names
| ?NotBlank | Len # prints 2

Optionally Assert Before Continuing to Pipe

! style can continue to passthru with write-error, or throw Filter can throw on a single item, or force the entire pipe to fail.

$userList
| !NotBlank -Property 'LastName', 'email'

# errors: outputs:
'AssertNotBlankException: {object type} properties are blank {property}'
@(
    New-Employee -LastName = 'Jen' -email 'Jen@somewhere.com'
    New-Employee -LastName = 'Bob'
)
| !NotBlank -Property 'LastName', 'email' -Fatal
| Write-ADRecord

# Throws. Write-ADRecord is not called with partial
'AssertNotBlankException: {employee} has a blank property {name}'

Error templates are generated by Info from the pipeline

?NotBlank filtering and !NotBlank style Asserts

$RequiredFiles
| !NotBlank -Reason 'Critical Config'
| Import-Config

# Exception: outputs:
'Critical Config {filename} failed {reason}'

$RequiredFiles
| ?NotBlank -Message 'Optional Config'
| Import-Config

# errors: outputs:
'Optional Config {filename} failed {reason}'

Native commands

Prevent spamming crazy windows when accidentally passing empty or broken strings to open in VS Code

$SearchResults
| ?NotBlank 
| Get-Item
| Out-VSCode

Some native commands don't accept / consume empty strings/nulls nicely. Newlines and Get-Content without -Raw.

Instead, remove all blank types

Get-Content -Path 'foo'
| ?NotBlank 
| Something.exe
function Embrace {
$Input | Join-String -op '[' -os ']'
}
Set-Alias 'Write-Color' Ninmonkey.Console\Write-ConsoleColorZd
Set-Alias 'Csv' -Value Csv2
& {
foreach ($x in 'a'..'f') {
"parent_id_$x.md"
@(
'new', 'files', 'modified'
| write-color 'green'
| csv
| Join-String -op 'Prefix: '
) | UL
}
}
Hr
& {
Get-ColorWheel
| ForEach-Object {
$curColor = $_
$curColor.X11ColorName | Embrace
| Write-Color -fg gray80 -bg gray20
@(
$curColor.R, $curColor.G, $curColor.B
| write-color -Fg $curColor
| csv
| Join-String -op 'Rgb: '
) | UL
}
}
& {
Get-ColorWheel
| ForEach-Object {
$curColor = $_
$curColor.X11ColorName | Embrace
| Write-Color -fg gray80 -bg gray20
@(
$curColor.R, $curColor.G, $curColor.B
| write-color -Fg $curColor
| csv
| Join-String -op 'Rgb: '
) | UL
} | ReverseIt
}
Set-Alias 'Write-Color' Ninmonkey.Console\Write-ConsoleColorZd
filter Test-StringIsNullOrWhitespace {
[OutputType('System.Boolean')]
[Alias('?NotBlank')]
param($InputText)
[String]::IsNullOrWhiteSpace( $InputText )
}
filter Assert-NotBlank {
[Alias('!NotBlank')]
[OutputType('Object')]
param($InputText)
if (Test-StringIsNullOrWhitespace $InputText) {
return $InputText
} else {
throw 'Not allowed'
}
}
function Csv2 {
$Input | Microsoft.PowerShell.Utility\Join-String -sep ', '
}
$sample = 'foo', 'bar', ' ', $null, ' cat'
$filesFromSomething
| ?NotBlank # prevents errors on null values
| Get-Item
| Out-VSCode
'foo', ' ', 'bar'
$names
| Len # prints 3
'foo', ' ', 'bar'
$names
| ?NotBlank
| Len # prints 2
$GoodUsers = $users
| SomeTransform
| ?NotBlank -Prop 'Name', 'Status'
$GoodUsers | Set-RegistrationCompletionEmail
$userList
| !NotBlank 'LastName'
| UL
function Format-UnorderedList {
<#
.EXAMPLE
PS> @(gi . ; get-date; 'hi', 'world') | ul
- C:\test\Format-UnorderedList
- 05/23/2022 20:28:17
- hi
- world
.notes
render-* implies ansi colors
.link
Ninmonkey.Console\Format-ShortTypeName
.link
Ninmonkey.Console\Render-ShortTypeName
#>
[Alias('UL')]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string[]]$InputObject
)
begin {
$Items = [list[object]]::new()
}
process {
$Items.AddRange( $InputObject )
}
end {
$Items | Join-String -sep "`n - " -op "`n - " -os "`n"
}
}
function Find-NotBlankProperty {
# Enumerate properties, except the blank ones
[Alias('?NotBlankProp')]
[OutputType('System.Management.Automation.PSNoteProperty[]')]
param(
[Parameter(Mandatory, ValueFromPipeline)]
$InputObject,
#Invert the logic
[Alias('Not')]
[Parameter(ParameterSetName = 'InvertTest')]
[switch]$OnlyBlank
)
begin {
$ConfigWantBlank = -not $Not
}
process {
# is a? System.Management.Automation.PSMemberInfoIntegratingCollection`1[System.Management.Automation.PSPropertyInfo]
# [PSMemberInfoIntegratingCollection<PSPropertyInfo>]
$InputObject.psobject.properties | ForEach-Object {
Write-Debug "PropIsBlank? Testing '$($_.Name)' of '$($_.Value)' "
$isPropNull = Test-StringIsNullOrWhitespace $_.Value
switch ($PSCmdlet.ParameterSetName) {
'InvertTest' {
if ($IsPropNull) {
return $_
} else {
return
}
}
default {
if ( -not $IsPropNull) {
return $_
} else {
return
}
}
}
}
}
}
<#
prints:
- user1
- user2
or throws exception:
Item Property 'LastName' must not be blank
#>
$sample
| ?NotBlank
| UL
Hr
$sample
| Join-String -Separator ', ' -DoubleQuote
| write-color -bg 'gray30' -fg 'gray80'
Write-Warning 'pseudo code'
<#
filter Format-DoubleQuoteItem {
# quote selft, but don't join all elements
[alias('Quote')]
param($InputText)
Join-String -DoubleQuote -InputObject $InputText
}
#>
Get-ChildItem .. -Depth 2
| Select-Object -First 6 | ForEach-Object Name
| ForEach-Object { $_ | write-color -fg (Get-ChildItem fg: | Get-Random -Count 1) }
function Assert-NotBlankWithProperty_sketch {
# future: mode that removes all properties that are null automatically
[OutputType('Object')]
[Alias('!NotBlank')]
[cmdletbinding()]
param(
[Parameter(ValueFromPipeline, Mandatory)]
$InputObject,
# property names to test
[ValidateNotNullOrEmpty()]
[Alias('Name')]
[Parameter(Position = 0, ParameterSetName = 'WithProperty')]
[string[]]$Property
)
process {
if ( [String]::IsNullOrWhiteSpace( $Property ) ) {
}
# $InputObject.Psobject.Properties
switch ($PSCmdlet.ParameterSetName) {
'WithProperty' {
$err = $Null
foreach ($prop in $Property ) {
$target = $InputObject.$Prop.value
Test-StringIsNullOrWhitespace $target -ev err
if ($Err) {
Write-Error 'object Property Named $Prop was blank'
return
}
}
}
default {
if (Test-StringIsNullOrWhitespace $InputText ) {
return $InputText
} else {
throw 'Not allowed'
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment