Skip to content

Instantly share code, notes, and snippets.

@macrat
Last active December 26, 2018 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macrat/3405a7e7fc93a4de1953c2c6248ef3cd to your computer and use it in GitHub Desktop.
Save macrat/3405a7e7fc93a4de1953c2c6248ef3cd to your computer and use it in GitHub Desktop.
powershellのスニペット集的なものを作りつつある。
<#
.SYNOPSIS
A snippets for powershell scripting.
.NOTE
It's WIP.
#>
<#
.SYNOPSIS
Ask file path with dialog box.
.PARAMETER Title
Title of dialog box.
.PARAMETER Type
Pair(s) of filetype and that name.
.OUTPUTS
A file path that choose by user.
.NOTE
An exception cause if user did cancell.
#>
function Ask-FilePath {
Param([string]$Title="Open file", [string]$Type="all files|*.*")
# TODO
}
<#
.SYNOPSIS
Write progress of pipe process.
.PARAMETER Activity
A text that describe what is processing for.
.PARAMETER Total
Total count of elements for processing.
.PARAMETER StautsText
A text that describe what is processing now.
This parameter will ignored if `StatusBlock` or `StatusProperty` are set.
.PARAMETER StausBlock
A ScriptBlock for generating text that describe what is processing now.
Passing current element as `$_` and `$input`.
.PARAMETER StautsProperty
A property name of element that describe what is processing now. This behave like a Select-Object
This parameter will ignored if `StausBlock` are set.
.PARAMETER EnableRemainTime
Display remain time if set this.
.PARAMETER Id
The ID of this process. Use for `ParentId`.
.PARAMETER ParentId
The ID of parent process. If it is -1 (that default), process will be root.
.EXAMPLE
$something | Write-PipeProgress -Activity "something" -Total $something.Count -StatusText "do something..." | Process-Something
.EXAMPLE
$people | Write-PipeProgress -Activity "read people data" -Total $people.Count -StatusBlock { "$($_.Name) ($($_.Age))" } | Read-People
.EXAMPLE
ls | Write-PipeProgress -Activity "ls" -Total (ls | Measure).Count -StatusProperty Name -EnableRemainTime | foreach { sleep 1 }
#>
function Write-PipeProgress {
Param([string]$Activity, [int]$Total, [string]$StatusText=$null, [ScriptBlock]$StatusBlock=$null, [string]$StatusProperty=$null, [switch]$EnableRemainTime, [int]$Id=0, [int]$ParentId=-1)
Begin {
$startTime = Get-Date
$status = if ($StatusBlock) {
$StatusBlock
} elseif ($StatusProperty) {
({ $input | Select-Object -ExpandProperty $StatusProperty})
} else {
({ $StatusText })
}
$count = 0
}
Process {
$seconds = ((Get-Date) - $startTime).TotalSeconds
$remain = if ($count -eq 0 -or -not $EnableRemainTime) { -1 } else { $seconds * ($Total - $count) / $count }
$s = $_ | & $status
if (-Not $s) {
$s = "${count} / ${Total}"
}
Write-Progress -Activity $Activity -Status $s -PercentComplete ($count * 100 / $total) -SecondsRemain $remain -Id $Id -ParentId $ParentId
$count++
$_
}
End {
Write-Progress -Activity $Activity -Completed -Id $id -ParentId $ParentId
}
}
<#
.SYNOPSIS
Get last element of inputs.
.INPUTS
Some elements for get last.
.OUTPUTS
The last element of input. `$null` if the input was 0 lengths.
.EXAMPLE
1..10 | Get-Last
10
#>
function Get-Last {
Begin { $x = $null }
Process { $x = $_ }
End { return $x }
}
<#
.SYNOPSIS
Get Range object of Excel.
.PARAMETER Sheet
The sheet for getting range.
.PARAMETER TopLeft
Top left position name of the range. Like "A2" or "R1C2".
.PARAMETER BottomRight
Bottom right position name of the range. Like "A2" or "R1C2".
.PARAMETER Top
Position address for the top of the range. This value will ignore if TopLeft has some value.
.PARAMETER Left
Position address for the left of the range. This value will ignore if TopLeft has some value.
.PARAMETER Width
The width of the range. This value will ignore if BottomRight has some value.
.PARAMETER Height
The height of the range. This value will ignore if BottomRight has some value.
.OUTPUTS
The range object of Excel.
.EXAMPLE
Get-Range $sheet -TopLeft "A1" -Width 2 -Height 3
# Same as `$sheet.Range("A1:B3")
.EXAMPLE
Get-Range $sheet -Top 4 -Left 5
# Same as `$sheet.Range("E4")
#>
function Get-Range {
Param($Sheet, [string]$TopLeft='', [string]$BottomRight='', [int]$Top=1, [int]$Left=1, [int]$Width=1, [int]$Height=1)
$tl = if ($TopLeft -ne '') {
$Sheet.Range($TopLeft).Cells.Item(1, 1)
} else {
$Sheet.Cells[$Left, $Top]
}
$br = if ($BottomRight -ne '') {
$Sheet.Range($BottomRight).Cells.Item(1, 1)
} else {
$Sheet.Cells.Item(($tl.Row + $Height - 1), ($tl.Column + $Width - 1))
}
return $Sheet.Range($tl, $br)
}
<#
.SYNOPSIS
Read a table from a Range object of Excel as an PSObject list.
.PARAMETER Range
The range object for get table.
.PARAMETER WithoutHead
The flag for don't care about header.
In default (if use it without this flag), read the first row of the range as a header and use as a property name of objects.
.EXAMPLE
Read-Table $range
hello world
===== =====
1 2
3 4
.EXAMPLE
Read-Table $range -WithoutHead
0 1
===== =====
hello world
1 2
3 4
#>
function Read-Table {
Param($Range, [switch]$WithoutHead)
$head = 0..(($Range.Column | Get-Last) - 1) | ForEach-Object { if ($WithoutHead) { $_ } else { $Range.Formula[$_] } }
$firstRow = if ($WithoutHead) { 0 } else { 1 }
for ($y = $firstRow; $y -lt ($Range.Row | Get-Last); $y++) {
$row = @{}
for ($x = 0; $x -lt $head.Count; $x++) {
$row.Add($head[$x], ($Range.Formula[$y * $head.Count + $x]))
}
New-Object PSObject -Property $row
}
}
<#
.SYNOPSIS
Convert array of PSObject to 2 dimensions array.
.PARAMETER Data
An array of PSObject to convert.
.PARAMETER WithoutHead
In default, the first row of output array are header. Wont include header if set this.
.PARAMETER Heads
Header texts for use to get property and export header row (only if not set WithoutHead).
#>
function ConvertTo-Table {
Param([array]$Data, [switch]$WithoutHead, [array]$Heads=$null)
if ($Heads -eq $null) {
$Heads = $Data | Get-Member | Where-Object { $_.MemberType -eq 'NoteProperty' } | ForEach-Object { $_.Name } | Sort-Object
}
$shift = if ($WithoutHead) { 0 } else { 1 }
$array = New-Object 'object[,]' ($Data.Count + $shift),($Heads.Count)
if (-not $WithoutHead) {
for ($i = 0; $i -lt $Heads.Count; $i++) {
$array[0, $i] = $Heads[$i]
}
}
for ($y = 0; $y -lt $Data.Count; $y++) {
for ($x = 0; $x -lt $Heads.Count; $x++) {
$array[($y + $shift), $x] = $Data[$y] | Select-Object -ExpandProperty $Heads[$x]
}
}
return $array
}
#$excel = New-Object -ComObject Excel.Application
#
#$book = $excel.WorkBooks.Open('tea.xlsx')
#
#$sheet = $book.WorkSheets[1]
#
#$range = (Get-Range $sheet -TopLeft 'A1' -BottomRight 'D3')
#(ConvertTo-Table (Read-Table $range))
#
#$excel.Quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment