The output of diff -q path1 path2 is pretty verbose. This function
Converts full paths to relative
Differences are red.
Missing ‘diff’ ?
If git is installed, you may need to update your %PATH% environment variable.
# in your profile
$Env:Path = "$Env:ProgramFiles\Git\usr\bin", $Env:Path -join ';'
Stand-Alone function Compare-Directory
This is an isolated version of <a href="https://github.com/ninmonkey/Ninmonkey.Console">Ninmonkey.Console: Compare-Directory</a> . I removed all dependencies except coloring is provided by the module PoshCode/Pansies.
function Invoke-NativeCommand {
<#
.synopsis
wrapper to both call 'Get-NativeCommand' and invoke an argument list
.example
PS> # Use the first 'python' in path:
Invoke-NativeCommand 'python' -Args '--version'
#>
param(
# command name: 'python' 'ping.exe', extension is optional
[Parameter(Mandatory, Position = 0)]
[string]$CommandName,
# Force error if multiple binaries are found
[Parameter()][switch]$OneOrNone,
# native command argument list
[Alias('Args')]
[Parameter(Position = 1)]
[string[]]$ArgumentList
)
$binCommand = Get-NativeCommand $CommandName -OneOrNone:$OneOrNone -ea Stop
& $binCommand @ArgumentList
}
function Compare-Directory {
<#
.SYNOPSIS
Compare Two directories using 'diff'
.EXAMPLE
Compare-Directory 'c:\foo' 'c:\bar\bat'
#>
[Alias('DiffDir')]
param(
# Path1
[Parameter(Mandatory, Position = 0)]
[string]$Path1,
# Path2
[Parameter(Mandatory, Position = 1)]
[string]$Path2,
# Output original raw text?
[Parameter()][switch]$OutputRaw
)
$Base1 = $Path1 | Get-Item -ea Stop
$Base2 = $Path2 | Get-Item -ea Stop
$Label1 = $Base1 | Split-Path -Leaf | New-Text -fg 'green'
$Label2 = $Base2 | Split-Path -Leaf | New-Text -fg 'yellow'
"Comparing:
Path: $Path1
Path: $Path2
" | Write-Information
$stdout = Invoke-NativeCommand 'diff' -args @(
'-q'
$Base1
$Base2
)
$outColor = $stdout
$outColor = $outColor -replace [regex]::Escape($path1), $Label1
$outColor = $outColor -replace [regex]::Escape($path2), $Label2
$outColor = $outColor -replace 'Only in', (New-Text 'Only In' -fg 'red')
$outColor = $outColor -replace 'Differ', (New-Text 'Differ' -fg 'red')
if ($OutputRaw) {
h1 'Raw' | Write-Information
$stdout
return
}
$outColor
}
function Get-NativeCommand {
<#
.synopsis
wrapper that returns Get-Item on a native command
.example
# if you want an error when multiple options are found
PS> Get-NativeCommand python -OneOrNone
.example
# note: this is important, $cmdArgs to be an array not scalar for '@' usage
$binPy = Get-NativeCommand python
$cmdArgs = @('--version')
& $binPy @cmdArgs
.example
#>
[cmdletbinding()]
param(
# Name of Native .exe Application
[Parameter(Mandatory, Position = 0, ValueFromPipeline)]
[object]$CommandName,
# One or None: Raise errors when there are more than one match
[Parameter()][switch]$OneOrNone
)
process {
try {
$query = Get-Command -Name $CommandName -All -CommandType Application -ea Stop
| Sort-Object Name
} catch [CommandNotFoundException] {
Write-Error "ZeroResults: '$CommandName'"
return
}
if ($OneOrNone -and $query.Count -gt 1) {
$query | Format-Table -Wrap -AutoSize -Property Name, Version, Source
Write-Error "OneOrNone: Multiple results for '$CommandName'"
return
}
if ($query.Count -gt 1) {
$query = $query | Select-Object -First 1
}
Write-Debug "Using Item: $($query.Source)"
$query
}
}
Sometimes you’ll need to run a command with the same input with different logic. This can be a hassle using a slow command like Get-ADUser or Get-ChildItem on a lot of files like ~ (Home) with -Depth / -Recurse
Power BI Discord asked the question: > How do you use duplicate keys, and dynamic urls with <a href="https://docs.microsoft.com/en-us/powerquery-m/web-contents">Web.Contents</a> ? (They were using a web API that required duplicate keys) After I wrote this, Chris Webb found an easier solution.
Requirements
You can’t use a regular record because keys must be distinct. Query = [ Key1 = 1, Key1 = 10] will throw an error.
You can’t put the **dynamic url** in the first argument Web.Contents or else refreshes can break
let
QueryStr_UsingDuplicateKeys = (key as text, values as list) as text =>
// values are the 'value' of 'key'-> 'value' pairs
let
escapedList = List.Transform(
values,
each
key & "=" & Uri.EscapeDataString( Text.From(_) )
),
joinedArgs = Text.Combine(escapedList, "&")
in
joinedArgs
in
QueryStr_UsingDuplicateKeys
Note: BaseUrl is for the static part of the url. Everything else should be in options[RelativePath] or options[Query] See docs: Web.Contents for details.
Which results in the url: <a href="http://jsonplaceholder.typicode.com/comments">http://jsonplaceholder.typicode.com/comments</a> This is a good place to use Power Query‘s null coalesce operator (Which isn’t in the official docs)