2019年04月

PowerShell コンソールの色を変更

コンソールの色が若干見ずらいので、Microsoftが提供しているツールを用いコンソールの色を変更する。

https://github.com/Microsoft/console

ツールのダウンロード

ColorTool.exeの実行

  • 保存したフォルダを開き、[shiftを押しながら右クリック]-[Powershellウィンドウをここに開く]
  • 主なオプション
    • .\ColorTool.exe -?
      ヘルプの表示
    • .\ColorTool.exe -s
      利用可能なすべてのカラーパターンを表示
    • .\ColorTool.exe -o <ファイル名.ini>
      現在のカラーパタンをバックアップ。出力されたiniファイルをschemesフォルダに移動することで、カラーパターンとして選択可能になる。
      注:バックアップを戻しても微妙に元に戻らないような気がする。色を何度か変えていくと、その順番によって、文字や背景色が異なる変わり方をするので、あまり役に立たないかもしれない。

  • 使用例
  • https://devblogs.microsoft.com/commandline/introducing-the-windows-console-colortool/

    カラーをsolarized_darkに変更

    .\ColorTool.exe solarized_dark
    

    このままウインドウを閉じると次回起動時に元に戻ってしまう。

    タイトルバーを右クリック→プロパティ→画面の色タブを開いてOKボタンをクリックすることで設定が保存される。

    ここまでは、「Powershellウィンドウをここに開く」から起動するコンソールの色を変更する手順。
    スタートメニューから起動するPowershellウインドウはデフォルトのままなので、そちらを変更したい場合は同様の操作をスタートメニューから起動して行う。

PowerShell SQLiteのSELECT結果からカスタムオブジェクトを作成する

SQLiteのSELECT結果から列名を要素にした連想配列を作成、それを纏めてオブジェクト配列を作成する。

Add-Type -path "System.Data.SQLite.dllを指定"
$conn = New-Object System.Data.SQLite.SQLiteConnection
$conn.ConnectionString = "Data Source = データベースファイルの場所" 
$cmd  = New-Object System.Data.SQLite.SQLiteCommand($conn)
$conn.Open()

$cmd.CommandText="select * from  jobs LIMIT 5"
#SELECT文の実行
$reader = $cmd.ExecuteReader()
#列名を取り出す
$colum=$reader.GetSchemaTable() | select ColumnName

#データが取り出せなくなるまでループ
$objs = while ($reader.read()){
            $colum | foreach -Begin {
                $obj=[ordered]@{}    
            } -Process {
                $obj += @{$_.ColumnName =$reader[$_.ColumnName].tostring()}               
            } -End {
                [pscustomobject]$obj     
            }
        }
出力結果
PS C:> $objs | Format-List

job_id     : AD_PRES
job_title  : President
min_salary : 20080
max_salary : 40000

job_id     : AD_VP
job_title  : Administration Vice President
min_salary : 15000
max_salary : 30000

job_id     : AD_ASST
job_title  : Administration Assistant
min_salary : 3000
max_salary : 6000

job_id     : FI_MGR
job_title  : Finance Manager
min_salary : 8200
max_salary : 16000

job_id     : FI_ACCOUNT
job_title  : Accountant
min_salary : 4200
max_salary : 9000
>
PS C:> $objs | format-table

job_id     job_title                     min_salary max_salary
------     ---------                     ---------- ----------
AD_PRES    President                     20080      40000     
AD_VP      Administration Vice President 15000      30000     
AD_ASST    Administration Assistant      3000       6000      
FI_MGR     Finance Manager               8200       16000     
FI_ACCOUNT Accountant                    4200       9000
htmlファイルにも出来る
PS C:> $objs | ConvertTo-Html -Fragment
job_idjob_titlemin_salarymax_salary
AD_PRESPresident2008040000
AD_VPAdministration Vice President1500030000
AD_ASSTAdministration Assistant30006000
FI_MGRFinance Manager820016000
FI_ACCOUNTAccountant42009000

取得件数を求めたい場合、件数が0件又は1件では$objs.Countで求めることが出来ないので、 先にオブジェクトが空かどうか見る処理を行うようにした。

#レコードの有無のみなら$objs -eq $nullだけで良い
if ($objs -ne $null){
    @($t.objs).Count
} else {
    0
}

単純に2次元配列で取得したい場合


$objs = while  ($reader.read()){
            $colum | % -Begin{
                $array=@()
            } -Process {
                $array+=@($reader[$_.ColumnName].tostring())
            } -End {
                ,@($array)
            } 
        }
for ($i = 0; $i -lt $objs.Length; $i ++){
    $objs[$i][0]
}
C:>
AD_PRES
AD_VP
AD_ASST
FI_MGR
FI_ACCOUNT

Powershell オブジェクトの内容をhtmlに出力

あまり有効な使い方は思い付かないが、csvファイルなんかをhtmlのテーブルに変換するのに便利かもしれない。

使用例

https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/ConvertTo-Html?view=powershell-6

以下のようなタブ区切りテキストをhtmlのテーブルに変換する。

札所    県    市
霊山寺    徳島県    鳴門市
極楽寺    徳島県    鳴門市
金泉寺    徳島県    板野郡
大日寺    徳島県    板野郡
地蔵寺    徳島県    板野郡
安楽寺    徳島県    板野郡
十楽寺    徳島県    阿波市
熊谷寺    徳島県    阿波市
法輪寺    徳島県    阿波市
切幡寺    徳島県    阿波市
$obj = Import-Csv .\tsvsample.txt -Delimiter "`t" -Encoding Default
$obj | ConvertTo-Html | Out-File tsvsample.html

以下のhtmlファイルが出力される

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/><col/></colgroup>
<tr><th>札所</th><th>県</th><th>市</th></tr>
<tr><td>霊山寺</td><td>徳島県</td><td>鳴門市</td></tr>
<tr><td>極楽寺</td><td>徳島県</td><td>鳴門市</td></tr>
<tr><td>金泉寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>大日寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>地蔵寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>安楽寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>十楽寺</td><td>徳島県</td><td>阿波市</td></tr>
<tr><td>熊谷寺</td><td>徳島県</td><td>阿波市</td></tr>
<tr><td>法輪寺</td><td>徳島県</td><td>阿波市</td></tr>
<tr><td>切幡寺</td><td>徳島県</td><td>阿波市</td></tr>
</table>
</body></html>

-Fragmentオプションをつけるとhtmlテーブルのみ生成出来る。

$obj | ConvertTo-Html -Fragment | Out-File tsvsample.html
<table>
<colgroup><col/><col/><col/></colgroup>
<tr><th>札所</th><th>県</th><th>市</th></tr>
<tr><td>霊山寺</td><td>徳島県</td><td>鳴門市</td></tr>
<tr><td>極楽寺</td><td>徳島県</td><td>鳴門市</td></tr>
<tr><td>金泉寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>大日寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>地蔵寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>安楽寺</td><td>徳島県</td><td>板野郡</td></tr>
<tr><td>十楽寺</td><td>徳島県</td><td>阿波市</td></tr>
<tr><td>熊谷寺</td><td>徳島県</td><td>阿波市</td></tr>
<tr><td>法輪寺</td><td>徳島県</td><td>阿波市</td></tr>
<tr><td>切幡寺</td><td>徳島県</td><td>阿波市</td></tr>
</table>

-Propertyオプションをつけると、特定の列を選択出来る。

$obj | ConvertTo-Html -Fragment -Property "札所","市" | Out-File tsvsample.html
<table>
<colgroup><col/><col/></colgroup>
<tr><th>札所</th><th>市</th></tr>
<tr><td>霊山寺</td><td>鳴門市</td></tr>
<tr><td>極楽寺</td><td>鳴門市</td></tr>
<tr><td>金泉寺</td><td>板野郡</td></tr>
<tr><td>大日寺</td><td>板野郡</td></tr>
<tr><td>地蔵寺</td><td>板野郡</td></tr>
<tr><td>安楽寺</td><td>板野郡</td></tr>
<tr><td>十楽寺</td><td>阿波市</td></tr>
<tr><td>熊谷寺</td><td>阿波市</td></tr>
<tr><td>法輪寺</td><td>阿波市</td></tr>
<tr><td>切幡寺</td><td>阿波市</td></tr>
</table>

特殊文字が入る場合

例えば以下のようにタグを入れる場合、このままConvertTo-Htmlすると"や<>が&quot;や&lt;に置き換わって出力されてしまう。

<a href = "https://ja.wikipedia.org/wiki/%E9%9C%8A%E5%B1%B1%E5%AF%BA_(%E9%B3%B4%E9%96%80%E5%B8%82)" target="_blank">霊山寺</a>  徳島県    鳴門市

&lt;a href = &quot;https://ja.wikipedia.org/wiki/%E9%9C%8A%E5%B1%B1%E5%AF%BA_(%E9%B3%B4%E9%96%80%E5%B8%82)&quot; target=&quot;_blank&quot;&gt;霊山寺&lt;/a&gt;  徳島県    鳴門市

ConvertTo-Htmlのオプションでは回避できそうにないので、出力後のhtmlファイルを編集するなりしないといけない。

とりあえず、ファイルに出力する前段階でreplaceで置換する方法を取った。

ここから丸写し

$replace = @{
'&quot;' = "`""
'&lt;' ="<"
'&gt;' = ">"
}

[regex]::replace(($objs | ConvertTo-Html | Out-String), ($replace.Keys -join "|"), {$replace[$args.value]}) | Out-File output.html

Out-Stringは無くてもいいかもしれない。

削除できないフォルダを削除する

以下windows10

robocopyの操作を誤って削除できないフォルダが作成されてしまった。

削除しようとすると"この項目は見つかりませんでした"とエラーが表示される。

rdコマンドで
rd \\?\削除したいフォルダのフルパス

で削除可能との情報もあったが状況は変わらず。

wslからrmコマンドで削除した。

rm -r mnt/削除したいフォルダのパス\ /

削除したいフォルダがc:\workだった場合

rm -r /mnt/c/work\ /

末尾の\ /の意味がよくわからないが、これをつけないと"No such file or directory"と受け付けてくれない。

パスの途中まで入力してTABキーで補完した際に自動で\ /まで表示される。

スクリプトの実行パスを知る

コマンドプロンプト

echo %~dp0
pause

PowerShell(v2迄)

Split-Path -Path $MyInvocation.MyCommand.Path
$r=Read-Host

$MyInvocation.MyCommand.PathはTABやctr+スペースのインテリセンス機能で候補が表示されないが入力すれば動く。

$MyInvocation.MyCommand.Sourceにするとインテリセンスで候補が表示されて同じ結果になるが、どう違うのかが解らない。

PowerShell(v3以降)

echo $PSScriptRoot
$r=Read-Host