Out-Fileで出力すれば良い話ではあるが、ダブルコーテーションを付ける場合はExport-CSVの方が楽かも
$ハードウエア一覧ヘッダー + "`r`n" + $ハードウエア一覧明細 | ConvertFrom-Csv | Export-Csv -Path .\ハードウェア一覧.csv -NoTypeInformation -Encoding Default
Out-Fileで出力すれば良い話ではあるが、ダブルコーテーションを付ける場合はExport-CSVの方が楽かも
$ハードウエア一覧ヘッダー + "`r`n" + $ハードウエア一覧明細 | ConvertFrom-Csv | Export-Csv -Path .\ハードウェア一覧.csv -NoTypeInformation -Encoding Default
変数で受け取った値を引数に使ってコマンドを呼び出す場合などに、省略された場合を考慮しないといけない。
Send-MailMessage -To $to ` -Cc $cc ` -From $from ` -Subject $subject ` -SmtpServer $mailServer ` -Body $body ` -Attachments $attachment ` -Encoding ([System.Text.Encoding]::Default) |
こんなケースで$attachmentに値が入ってこないとエラーになる。
だからと言って引数の組み合わせの分だけコマンドを用意するのも・・・。
なんか簡単に解決できる方法がありそうにも思うが、見つからなかったのでとりあえず以下の様にしてみた。
$param = @{ "To" = $to "Cc" = $cc "From" = $from "Subject" = $subject "SmtpServer" = $mailServer "Body" = $body "Attachments" = $attachment "Encoding" = [System.Text.Encoding]::Default } if($attachment -eq ""){$param.Remove("Attachments")} Send-MailMessage @param |
アクセス権が無くて管理者でも消せなくなるフォルダー(ファイル)がある場合。
(移動プロファイルのフォルダーとか普通になっても管理者がアクセスできなくなる)
所有権を取れれば問題ないのだがGUIからは所有権も取れない場合もある。
そんな時は以下のコマンドで、
takeown /f c:\users\username /r /d y
$dn = (Get-ADUser -Identity "testUser").DistinguishedNameRename-ADObject $dn -NewName "新氏名"
ADのサブネットをコマンド設定するときに「New-ADObject」を使うようなのだが、その中で以下の様なプロパティがある
-OtherAttributes @{location="Building A";siteObject="CN=HQ,CN=Sites,CN=Configuration,DC=FABRIKAM,DC=COM"}
サブネットがたくさんあるとループしながらフォーマット演算子で可変部分を入れ替えてとなるのだが、フォーマット演算子と連想配列を一緒に使うとエラーとなる。
{}の扱いがよろしくない。
連想配列側の括弧を2重にすると良いようだ。{{hoge}}のように。
Out-GridViewにデータをパイプしている最中(時間が掛かっている時)にGridの画面を閉じてしまうと(時間が掛かるからやーめたってパターン)Powershellが落ちてしまうようです。
以下と見るとBUGのようなので余り対策は無さげですが、
パイプするデータを予め変数に入れてから繋ぐか、メッセージを出してパイプが終わるまで待ってもらう感じですかね。
PowerGUIを使うとスクリプトを簡単にExeへと変換できるようだ。
(いつのバージョンから出来るようになったのか定かではないが、比較的最近だと思われる)
必ずしもPowerGUIの専売特許という訳では無さそうですが・・・。
Make-PS1ExeWrapper | Keith Hill's Blog
「ツール」メニューから「Compile Script...」を選んで
同じ場所にConfigファイルも作られるようだが、とりあえず無くても動作はするみたい。
何かしら制限があるのか無いのか、使いこんだわけではないので判らないが、さしあたって実行ポリシーは回避できるようだ。
ちょっと便利かも。
Compileの下にServiceを作るメニューもある・・・。
----
最近ではPS2EXE-GUIあたりが良さそう(2021/08/25)
EPPlusがやっと動くようになって元々の目的だった完了日欄に日付を入れてみた。
$sheet.Cells["N4"].Value = “2021/03/19”
フォーマット的には「2021年 03月 19日(金)」と表示されるはずなのだが、そのまま「2021/03/19」と表示されてしまう。
一旦セルにフォーカスを当ててEnterを押すとちゃんとフォーマットされるので値自体は問題なさそうなのだが。
EPPlus側でフォーマットを再設定などしても変わらず。
他の数値書式なども試してみたのだがそちらは問題ないので強制的にフォーマットを適用させる必要があるとかでは無さそう。
半日ほど彷徨った結果やっと判った。
要は、Excel君は賢いので“2021/03/19”という文字列を日付の事だろうと忖度してくれて日付型にパースする。
ただ、このタイミングがセルの編集終わりなので手入力の時は良いがEPPlusが設定した値までは面倒見てくれない。
EPPlusは“2021/03/19”が文字列なのでそのままセルに突っ込んで終わり。
これを「EPPlus様」に書式設定してもらうには、
$sheet.Cells["N4"].Value = Get-Date
の様に日付型を突っ込めば良いだけだった。
ふぅ~。
Excelが無い環境(サーバー)でExcelにたった1項目(完了日付)を入れたいだけだったのに、EPPlusのインストールに始まり、上手くいかずClosedXMLへ移り、やっと環境ができて動いたかと思えばオブジェクトが扱えずにEPPlusへ戻り、依存関係に悩みながらやっと動いて値が設定できたかと思えば書式が反映されず。
っと都合3日ほど掛ったのではなかろうか・・・・。
動いてしまえば、Excelの様な巨漢を必要とせず一瞬で終わる処理は気持ちが良いものだ。
10年ほど前にいくつかのパターンを試したのだが今となっては以下のEPPlusを使うパターンとか環境をどう作ってい良いかよく判らない。
コーディング自体も変わっているのかも。
http://mtgpowershell.blogspot.com/2012/10/excelexcelepplus.html
いくつか調べてみると「ClosedXML」を使ったパターンの情報がいくつか見つかったのでそちらを使ってみることとした。
Powershell、というかコーディング自体ちょっと現場を離れて長いので半分浦島太郎状態で躓いてばかり。
あまり理解しているわけではないがとりあえず動いたので情報をメモしておく。
環境的には以下を参考にさせていただいた。
https://qiita.com/HAGITAKO/items/05328043d599964c485d
管理者権限でまずは、
Install-PackageProvider -Name Nuget
これは多分1回やっておけば良いのだろう。
次に必要なパッケージをインストール。
ここでは「DocumentFormat.OpenXml」と「ClosedXM」を入れる
Find-Package -Name DocumentFormat.OpenXml -Source https://www.nuget.org/api/v2 -RequiredVersion 2.7.2 | Install-Package -SkipDependencies
Find-Package -Name ClosedXML -Source https://www.nuget.org/api/v2 -RequiredVersion 0.95.4 | Install-Package -SkipDependencies
OpenXMLはバージョンが悩ましい。
上記で参照したサイトでは「2.5.0」を使っていたがどうも「ClosedXML」のバージョンとの組み合わせがあるようで・・・。
このサイトで使っていた「ClosedXML」の「0.76.0」のバージョンは既にダウンロードができず、やむなく新しいバージョンを使うと(ここでは最新っぽい「0.95.4」を使用)動かない。
以下のサイトで「2.7.2」が良いとの情報がありそれを使ったら動いた。
https://f-journey.com/it/install_closedxml_on_powershell
また、install-packageはそのままだと
install-package : Dependency loop detected for package 'DocumentFormat.OpenXml'.
とか言ってエラーになるのでスキップするオプションを付けてあげればとりあえず良さげ。(いろいろと悩ましい・・・)
実際のPowershellソースの方はこんな感じで。ちなみに.NETの4.0を指定しているのは適当です。
add-type -path "C:\Program Files\PackageManagement\NuGet\Packages\DocumentFormat.OpenXml.2.7.2\lib\net40\DocumentFormat.OpenXml.dll" $inpath = "C:\Users\hogehogeUser\Desktop\test.xlsx" |
SCPでLinuxサーバーからファイルをコピーしていたのだが、まれにファイルが無い時があることが判明。
存在確認をした上でコピーしたいのだが(もしくは存在しなくてもエラーを出さない)SCPのオプションでは無さそう・・・。
SFTPとかを使った方が良いのだろうか。
何分ここら辺の事は素人でよく判らない。
とりあえずSCPの前にSSHコマンドで確認することとした。
| $fileExist = ssh $user@${hostName} "if [ -f /tmp/bkup.tar ]; then echo 'exist'; else echo 'not exist'; fi" |
確か昔も嵌ったことがあってもしかするとどこかにメモしたのかもしれませんが再度。
start-process powershell.exe -Credential $cred -ArgumentList ("-command dir -noexit " ) |
このexitパラメータが効かなかったりするのだが、なぜかパラメータの先頭にするとOK。
Powershellっぽくて、こういう話は好きです。
簡単に言えば、
$a = 1 |
| $a = 1 ; $b = 2 |
って1行にも書けるよ。
てのと、
「,」と「+」は「,」が優先ねってだけの話だと思うのですが一見すると摩訶不思議にも思えるってところでしょうか。
まぁ、配列の区切りは「,」だけを使う人がほとんどでしょうから嵌る人はまずいないでしょうけど。
イベントログのチェックをしています。
昇順に読んでチェックするのに日付でソートすりゃ良いのかと思ったのですが秒までしかないので同じタイミングで出力があるとソート後の並びが担保されない。
仕方がないのでソートせずに逆順にして読もうかと・・・。
正当な方法は無さげなので以下を参考にしてやってみた。