PowerShell -Part 3

■ このスレッドは過去ログ倉庫に格納されています
2018/10/09(火) 17:46:48.32ID:G4IJkzod
前スレ
【最強CUI】PowerShell -Part 2
http://mevius.5ch.net/test/read.cgi/tech/1480109402/
237デフォルトの名無しさん
垢版 |
2018/11/19(月) 21:26:04.01ID:Gl33OQrV
投稿がまともになってきた
2018/11/23(金) 16:20:10.48ID:5fd0Mgpu
Effective PowerShell的な本ってないの?
普段、使う分には問題なく使えてると思う
でもより上手い書き方があるのでは、良いコーディング習慣を守れてるだろうか、と自問自答すると自信を持てない
人に見せるものでもなく、人のを見る機会もないからどうしても自己流になってしまう
2018/11/23(金) 22:10:45.37ID:ZSsoDLJq
本じゃないけど

PowerShell のコーディングスタイル
http://tech.guitarrapc.com/entry/2017/12/03/230119
2018/11/23(金) 22:36:58.28ID:b8tU0Ani
文法詳説はこの前出た貝殻本が扱ってたけど
読みにくい(演算子の説明が130ページくらいから始まる)
2018/11/24(土) 01:01:38.61ID:sK2Z8lS/
バイナリモジュールの情報少ないよなあ
github漁ってもあんまりないし
コマンドレット内でGet-Item呼び出す方法探すだけでだいぶ苦労した
結局ダサいやり方になったけど
2018/11/24(土) 02:06:29.51ID:mWKK19aP
powershell深いなあ。深すぎてちょっと目眩する時がある
2018/11/24(土) 03:37:58.44ID:BKTpjWqm
get-netadapterとか見たいに複数の結果を返すようなクラスが作りたいんだけど
どんな感じで書けばいいん?
思い浮かばねえorz
2018/11/24(土) 03:58:00.19ID:wk1txPAQ
>>243
Function内でWrite-outputでクラスを複数回出力するとか
クラスの配列を返せばいいよ
2018/11/24(土) 04:04:11.42ID:BKTpjWqm
>>244
ちと理解できてない
例えば、get-netadapterの内容を編集して結果をだすクラスを作るとして
インプットが複数なのでそれを都度かえしていくってことでいいのかな?
2018/11/24(土) 05:43:08.48ID:wk1txPAQ
>>245
まず作りたいのはクラスじゃなくてFunction(関数)かメソッドかコマンドレット(外部関数)だよね?
クラスは型であって入力と出力を持つものでは無いし

Get-netadapterも含めて一般的なコマンドレットの出力型は配列で
配列の各要素がクラスになってる

Get-netadapterの結果に編集を加える場合、
入力された値をforeach等で分解して
クラスにAdd-member等で要素(プロパティとか)を加えて毎回出力するとかする

もしくは配列の各要素がPSCustomObjectクラスの変数を作って
それを出力するとかする

サンプルに丁度よい関数とかあればいいけど一端探すのめんどいから割愛
Add-memberとかクラスのメンバーについてはググって調べて下さいな
2018/11/24(土) 09:11:34.28ID:kuH8s62I
この手の話題でクラスとインスタンスの区別をせずに語られるとすごくモヤモヤする
2018/11/24(土) 12:12:31.33ID:+C2yOPuj
PSVersion 5.1.17763.134
PSEdition Desktop
で Windows.Forms.Timer がちゃんと動いてくれぬ
Tickイベント内の変数の変更を保持してくれない?
2018/11/24(土) 12:54:26.03ID:BKTpjWqm
>>246
ごめん、違う
2018/11/24(土) 13:22:16.60ID:BKTpjWqm
途中で切れてしまった
コンストラクタに引数設定できるでしょ
その引数にget-netadapterの結果みたいなのを使う
で、その値で各プロパティの初期値みたいなのをセット
各引数付きのメソッドを実行すると、引数とプロパティを処理した結果を返すんだけども
get-netadapterみたいに複数がコンストラクタのインプットになるから、どうしたもんかと
やっぱ、無理なのかな
2018/11/24(土) 13:44:41.51ID:QuuVAkmI
UTF-8を標準出力に出力するexeの結果を処理したいのですが
特定の文字が入っていると文字コード変換に失敗します
例えば以下の文字列はこのように文字化けします
 「ホスト#01」⇒「ホスチE01」
 「ホスト02」⇒「ホスチE2」

正しくPowerShellで扱える文字列に直す方法をアドバイスいただけないでしょうか

## ソース
$src = [System.Text.Encoding]::UTF8
$dst = [System.Text.Encoding]::Default
$test = & 'C:\test\UTF8.exe'
$bytes = $dst.GetBytes($test)
$result = $dst.GetString([System.Text.Encoding]::Convert($src,$dst,$bytes))


UTF-8を標準出力に出力するサンプルexe(C#)
Console.OutputEncoding = new UTF8Encoding();
Console.WriteLine("ホスト#01\r\nホスト02");
2018/11/24(土) 14:43:41.10ID:2Kjdv9to
>UTF-8を標準出力
でぐぐったら
>これで、UTF-8 を使うアプリとの連携もばっちりだ。
そうだ
2018/11/24(土) 14:43:42.28ID:+C2yOPuj
>>251
PowerShellの内部でのエンコードはたしかUTF16じゃないかな
2018/11/24(土) 16:43:37.74ID:QuuVAkmI
>>252
このスレに書き込んで説明するために標準出力って持ってきたのですが
ググってるときは標準出力って思いつかずサイトに巡りあえませんでした
おかげでなんとかなりそうです
ありがとう

>>253
UTF16だという情報もみて変えてみたりもしたのですが、
余計文字化けがひどくなったのでどう対応すべきか悩んでました
255デフォルトの名無しさん
垢版 |
2018/11/25(日) 01:27:52.64ID:bdma9Nzw
文字コードなど、考えたこともない。
UTF-8 しか使わないし

どのOS・アプリでも内部的には、UTF-16 だろうけど、これを扱うことなどない
256デフォルトの名無しさん
垢版 |
2018/11/25(日) 01:44:12.14ID:fZE2Z+wN
http://altohumano.com/gt-r%e3%80%80%E8%B2%B7%E5%8F%96/
2018/11/25(日) 10:54:09.80ID:Vpi5v0vn
PowerShellの変数ってちゃんと型指定したほうがいいの?
2018/11/25(日) 19:55:30.63ID:aKGD81aI
パフォーマンス気にして型変換するなら、Powershell使うこと自体が不適
通常は勝手に型変換しないように型付ける

v3のビットシフト演算子が勝手にbyte型をint型にキャストするのマジ糞
2018/11/25(日) 19:55:52.89ID:aKGD81aI
>>258
パフォーマンス気にして型「指定」だわ
2018/11/25(日) 20:30:16.12ID:dc9uTwTH
powershellにintegral promotionは定義されてないのか
2018/11/25(日) 21:22:56.96ID:XYd2EWob
未だにバッチをメインで使っている
ぼちぼちPowerShellメインに変えようかと思っているんだが
WSHもどうか?とおもったり
もうWSHは終わりで、PowerShellが延びると思っていて良い?
2018/11/25(日) 23:19:09.06ID:NeSEBBpr
VBScriptはちょっとオワコン感出てきたけど、WSH自体はJavaScriptがデフォルトで使えるのでしぶとく残りそう
2018/11/25(日) 23:34:35.24ID:tkP11man
>>261
標準で備わってる機能面でwshはPowershellに比べて貧弱だよ
Powershellだとcsv読み込むとかjson処理するとかコマンドレットで用意されてるけどwshだとそれなりのコード書かないと出来ないし
ループ周りもパイプラインに比べると冗長になりがち

ただwshの方がシンプルで学習は楽、Powershellは複雑な部分が多い
学習コストはPythonより高い気がする
2018/11/25(日) 23:48:06.15ID:tkP11man
PowershellはMS系クラウドサービスの管理シェルとして伸びるかな
バッチもwshも消えなそうだけど今後の伸びは無さそう
2018/11/26(月) 02:18:11.89ID:beMkVqx1
手を広げ過ぎて仕様が複雑というより単に雑な印象がある
2018/11/26(月) 02:57:13.19ID:gMbJcsFf
学習コスト高いというか体系的にまとまった書籍等無いからよくわからずに動く状態になる(配列とか)
Pythonのようにすんなり上達するのではなくて、ある程度学ぶとかえってわからなくなるの繰り返し

それでも今更wshやるよりはいいはず
2018/11/26(月) 03:29:58.94ID:x+j35ljp
PowerShellだと学習コストは高いけど
よく使うコマンドレットがそろってる

WSHだとJavaScriptで書けるけど
自作ライブラリみたいの書く手間はある

微妙な勝負だけど今から始めるならもう
Poshを使ってしまった方が良いと思う
2018/11/26(月) 08:10:27.64ID:8ZmTpMnp
>>262
いやちょっとどころじゃねーだろ
いつの時代の話してるんだか
2018/11/27(火) 02:30:28.91ID:tmYINXAW
未だにバッチでこと足りてしまう管理業務というのが想像できない。
2018/11/27(火) 07:41:39.02ID:WLNYjP7B
VBSはバリバリ現役よ
うちの社内システム開発・運用は全てVBS
無料であり
バッチファイルより遥かに強力で
仕様が枯れていてVerUPに振り回されることがなく
Javaのように一企業の思惑でライセンス問題が発生することもない神言語
PowerShellはerUPが止まり仕様が枯れるまでは採用しない
2018/11/27(火) 07:53:06.65ID:wHi5iJt/
>>270
WIN10のストアアプリの削除もVBSで出来るの?
2018/11/27(火) 08:04:37.56ID:WLNYjP7B
>>271
うちはWin7
2018/11/27(火) 09:20:49.19ID:pR/1ZC3V
Win7はあと1年ちょいでサポート終了だしな
その後はWin10のPowershell5.1で標準化するでしょ
今のPowershellは2.0が残ってるのがガンになってる気がする
2018/11/27(火) 09:48:14.11ID:PCREN6ZT
>>270
Windows PowerShellはとっくにバージョンアップ止まってるんだが何が不満なんだ
2018/11/27(火) 13:25:38.77ID:n8g+btBw
>>270
5.1がWinにおける最終バージョンだろ
2018/11/27(火) 17:49:55.92ID:GQ1LL4CF
5.1だと正常に動かなくて
v2オプジョンだとちゃんと動くのとかあるし…
277デフォルトの名無しさん
垢版 |
2018/11/27(火) 18:27:04.57ID:7LglyRgp
>>276
どんなのがあったっけ?
2018/11/27(火) 19:10:08.25ID:d01YhI4a
今だとUIフォームつくるならWPF?
2018/11/27(火) 23:03:49.22ID:5h6j1xJ1
JP1のSPTファイルもぶっちゃけVBSみたいなもんだよね
2018/11/27(火) 23:18:31.25ID:X/MEoliS
>>273
win7 はたぶん終了にならないと思います、win10 がクソすぎるからね
2018/11/28(水) 09:58:30.52ID:dGZ6nyrF
>>280
神OS(笑)XPの時も似たような話聞いたわ
2018/11/28(水) 11:20:24.48ID:b089yY0z
Win7はデフォでv2.0しか使えないからこのスレ的にはダメダメ
283デフォルトの名無しさん
垢版 |
2018/11/28(水) 12:31:06.61ID:j69eTZ+j
>>282
デフォルトじゃないとだめなの?
2018/11/28(水) 12:57:23.83ID:036JocE6
有償で延長サポートの話が出てる以上
それ以外はバッサリ終了に決まってるでしょ
2018/11/28(水) 19:59:03.72ID:b089yY0z
>>283
出先でWMF入れられないじゃん
286デフォルトの名無しさん
垢版 |
2018/11/28(水) 21:40:54.00ID:e3ALQLMX
>>285
なるほどね。仕事内容や立場により、いろいろあるわけね。
2018/11/28(水) 21:55:44.64ID:JxqTGA2g
これが5.1だとちゃんと動かねぇ
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

function ShowInfoMain{
$counter = 0
$timerTestTick = {
$label_timer.Text = "{0} 秒" -f $counter++
}
#タイマーの初期化
$timerTest = New-Object Windows.Forms.Timer
$timerTest.Add_Tick($timerTestTick)
$timerTest.Interval = 1000
$timerTest.Enabled = $TRUE
$timerTest.Start()

#フォーム
$Form = New-Object System.Windows.Forms.Form
$Form.Size = "100,100"
$Form.StartPosition = "CenterScreen"

#タイマー
$label_timer = New-Object System.Windows.Forms.Label
$label_timer.Text = '0 秒'
$Form.Controls.Add($label_timer)

$result = $Form.Showdialog()
$timerTest.Dispose()
$Form.Dispose()
}
. ShowInfoMain
2018/11/28(水) 23:01:00.54ID:b5TbM/Zv
$counter = 0
$label_timer = New-Object System.Windows.Forms.Label
$timerTestTick = {
$label_timer.Text = "{0} 秒" -f $script:counter++
}
2018/11/28(水) 23:05:36.16ID:b5TbM/Zv
順序関係なく単純に $script:counter++にするだけでいいみたいやね
2018/11/28(水) 23:27:13.98ID:JxqTGA2g
んがー
スクリプトブロックでのスコープによるものって
認識でよろしいのだろうか…
2.0だと動くのはなんでなのじゃ
2018/11/28(水) 23:38:49.55ID:JxqTGA2g
>>289
ありがとうございました

初期値の宣言でもやんないとダメみたい
$script:counter = 10
2018/12/02(日) 21:23:25.18ID:u3CI+74z
PowerShell 3.0での破壊的変更まとめ
https://blog.shibata.tech/entry/2018/12/01/113228

デリゲート代わりに使われるスクリプトブロックのスコープ

PowerShell 3.0からデリゲート代わりに使われるスクリプトブロックが独自のスコープを持つようになっています。
たとえば以下の様な例だとPowerShell 2.0では1を、PowerShell 3.0からは0を返す様になります。

Add-Type @"
public class Invoker
{
public static void Invoke(System.Action<int> func)
{
func(1);
}
}
"@
$a = 0
[Invoker]::Invoke({$a = 1})
$a
293デフォルトの名無しさん
垢版 |
2018/12/03(月) 14:13:32.11ID:xHLM582p
新しいpowershell では、Get-Clipboard で、クリップボードから文字列も取得できる!
2018/12/03(月) 20:49:19.87ID:9uCJpuZ+
んなもん.NET直接呼んだ方が互換性高い
2018/12/03(月) 21:32:04.89ID:uxAfgW4c
なんでそんなめんどくせーことせなあかんねん
2018/12/03(月) 22:42:10.02ID:YBAcFOR9
>>295
powershellは.netのフロントエンドだから
2018/12/03(月) 22:51:11.92ID:uxAfgW4c
そういう問題じゃないが・・・
支障がない場合はそんまま使うわあほくさ
2018/12/04(火) 02:28:30.75ID:Tn5NKjZ7
なんで今更5.0の話してんのさ
299デフォルトの名無しさん
垢版 |
2018/12/04(火) 16:12:13.82ID:eKuwOju4
5ch の文章を、テキストエディタへコピペすると、
各行の先頭・末尾に、空白が付くので、これを除去したい

そこで、Ruby でプログラムを作って、
バッチファイルで、そのプログラムをダブルクリックで起動できるようにした

Windows で、クリップボード内の複数行文字列の、各行の先頭・末尾から、
連続する空白類を除去して、クリップボードに入れる

新しいpowershell では、クリップボードから文字列も取得できる

str = `powershell Get-Clipboard`
str.encode! Encoding::UTF_8, Encoding::CP932 # UTF_8 へ変換

ary = str.each_line.map( &:strip )

IO.popen( 'clip', 'w:cp932' ) do | clip |
clip.print( ary.join "\n" )
end
2018/12/04(火) 17:07:32.91ID:hkRngAzE
Get-Clipboardの機能は2015年からあるがどう新しいのか
2018/12/04(火) 17:45:54.20ID:xb7Yz2vd
Ruby挟む意味ないじゃん?バッチも画面が目ざわりだしvbsがいいよ

CreateObject("WScript.Shell").Run "powershell ""gcb | % trim | scb""", 0
302299
垢版 |
2018/12/04(火) 19:47:12.62ID:eKuwOju4
VBS でも、ダブルクリックで実行できる?
303299
垢版 |
2018/12/04(火) 19:58:07.57ID:eKuwOju4
ありがとう。
VBS でも、ダブルクリックで実行できた

ただ、黒い画面が表示された方が、わかりやすくない?
何秒ぐらい待つのか、迷う
2018/12/04(火) 21:38:59.01ID:gx9huxXd
Windows文化は「黒い画面」が出るのを良しとしないのだよ
2018/12/04(火) 22:20:16.69ID:SeIDr86X
>>304
そんなの一部の神経質な奴らだけ
2018/12/04(火) 23:31:35.16ID:RbfFY42H
>>305
Windows 文化と言うより、業務でオツちゃん・オバちゃんに使わせるシステムの場合、
あいだに黒い画面が一瞬出ると「なにこれ?」って無用な問い合わせが入ったり、
場合によっては無理やり閉じられることもある。
fool proof の観点からは黒い画面が無いに越したことはない。
2018/12/05(水) 20:37:03.12ID:x9ea9mMQ
" が含まれている文字列を環境変数にいれてnet useコマンドを使うと" がエスケープされず想定通りに処理されないのですがどうエスケープすればいいんでしょうか
シングルコーテート、バックコーテート、ダブルコーテートで"をくくってもだめでした
2018/12/05(水) 20:49:13.75ID:jRzepDw/
何をしたくて何をしているのかさっぱりわからん
2018/12/05(水) 20:58:21.39ID:x9ea9mMQ
たとえばですが
$pass = test123"45
net use c:¥temp ¥¥192.168.1.10 $pass /user:testuser

とした時にパスワードに含まれている"が文字列として認識されずコマンドが実行されないのです
これをエスケープしようと
$pass = test123"""45
$pass = test123'"45
などとしてもうまくいかない感じです
2018/12/05(水) 20:59:28.32ID:0urcwekh
net useはpowershellのコマンドプロンプト用、powershellではNew-Psdriveコマンドレット、powershellのエスケープ文字は基本バックスラッシュ`
2018/12/05(水) 21:00:28.08ID:0urcwekh
WSHとごっちゃにしないでね
2018/12/05(水) 21:01:52.08ID:0urcwekh
1行目間違えた
net useはコマンドプロンプト用
2018/12/05(水) 21:03:52.33ID:x9ea9mMQ
net use ではなく new-psdriveだとバクスラでエスケープ可能なんですか?
net useだとエスケープできなかったので、ちょっとやってみまふ
2018/12/05(水) 21:08:28.49ID:x9ea9mMQ
ちなみにパワーシェルからcmd /cでコマンド呼び出すときのエスケープキーはバクスラと^のどちらですか?
2018/12/05(水) 21:10:17.22ID:0urcwekh
本件は
$pass='123"45'
とすればいいだけ
2018/12/05(水) 21:16:36.03ID:x9ea9mMQ
シングルコーテートでくくってもエスケープできるんですね
ありがとうございます
2018/12/05(水) 21:23:21.81ID:0urcwekh
エスケープじゃなくて、Powershellでは文字列は必ず'か"どっちかで囲う。生身はだめ。'で囲うのは静的リテラルの場合
2018/12/05(水) 21:25:50.83ID:jRzepDw/
結局環境変数は関係ないのか?
> " が含まれている文字列を環境変数にいれて
2018/12/05(水) 21:30:22.57ID:0urcwekh
本当の初学者で変数もコマンドプロンプトと同じ概念なんだろ
2018/12/05(水) 21:57:08.28ID:x9ea9mMQ
なるほどそういうルールあるんですね
プログラムやったことないんでしらんかったす
リテラルってのも意味わからんかったくらいや
2018/12/05(水) 22:13:06.29ID:ix5zH8Lr
start-processで終了を待たずにps1実行していくのは疑似並列処理として考えて良いのでしょうか
2018/12/06(木) 07:24:42.90ID:Ia5EZXvv
「`」はバッククォートだ馬鹿者
バックスラッシュ(\)とは違う
2018/12/06(木) 08:11:29.70ID:XlsCLRxJ
PowerShell Coreの宣伝始まった

https://twitter.com/Steve_MSFT/status/1070096140010287104
https://twitter.com/5chan_nel (5ch newer account)
2018/12/06(木) 12:49:27.99ID:r+yxrRWT
標準出力に変なもん混ぜるな
325デフォルトの名無しさん
垢版 |
2018/12/06(木) 14:36:39.70ID:8XTishpu
>>309
間違いないよう(見間違いも)にだったらヒアストリングつかったらどうでしょう
行は増えますが、エスケープ考える必要もかいから。

@"
test123"45
"@
2018/12/07(金) 00:30:59.21ID:d/eT01GS
whoamlで取得した実行結果のユーザ名を一行で環境変数に入れるにはどうすれば良いでしょうか

whoami 実行
結果 testpc¥user1
と結果が返ってくる場合、
$test = whoami.split("¥")[1]
と言ったかたちで
$testにuser1を格納させたいのですがうまく行きません
2018/12/07(金) 01:04:59.92ID:frCtIBO+
括弧で囲む
(whoami)
2018/12/07(金) 03:14:11.72ID:0M/LMioQ
>>326
昨日と同じ人だと思うけれどpowershellでは変数はコマンドプロンプトとは違い環境変数ではありません。

http://www.atmarkit.co.jp/ait/spv/0709/20/news125_2.html
2018/12/07(金) 07:51:42.00ID:QVqNOX9I
読んでみたけど違いがよくわからん
型を持つってとこ?
2018/12/07(金) 08:45:51.25ID:hrhTiXxm
型じゃなく範囲・スコープだよ
環境変数はOSが管理していて、ひとつ値をセットしたら同じ環境内の他プロセス(アプリ)がその値をOSに教えてもらえる
普通の変数はプロセス内で管理されていて、他プロセスは見ることが出来ない
2018/12/07(金) 12:18:05.50ID:cSzYN2du
Linux では、~/.bashrc に環境変数を書けば、
自分(そのユーザーだけ)が起動するプロセスから、アクセスできる

etc/ 以下なら、PC 全体の設定になる

~/.bashrc は、Windows ではユーザー環境変数。
一方、システム環境変数は、PC 全体の設定で、すべてのユーザーで共有される

例えば、Tで始まる環境変数なら、
ls env: | Where-Object {$_.name -like "T*"}
2018/12/07(金) 12:42:27.81ID:TQVSWTyy
>>326
それを実行している自分自身のユーザ名が欲しいだけなら、わざわざそんなことしなくても
$env:USERNAME
で引っ張ってこれる。

出し惜しみ、小出しにしないで前後関係も話さないと的確なアドバイスが出来ないよ。
2018/12/07(金) 16:32:33.86ID:fTv51LPz
>>331
.bashrcはPowershellでは$Profileに当たると思うわ
2018/12/07(金) 17:14:53.01ID:2MiN5Gqm
つーか、Credential使えよ
今時ハードコートとかありえん
2018/12/07(金) 17:53:23.13ID:TQVSWTyy
>>334
だね。
どうやら ID:x9ea9mMQ ID:d/eT01GS はネットワークドライブのマウントがやりたいようだけど、
dos batch で使うべき net use や whois を PowerShell で使おうとすることに
無理がある。出来なくもないけどエレガントじゃない。

PowerShell でやるなら New-PSDrive だな。
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-psdrive
-Credential で任意の(自分以外の)クレデンシャルも指定できるから、
ID:x9ea9mMQ の要件も(たぶん)満たせるだろう。
2018/12/07(金) 18:35:56.11ID:fTv51LPz
コマンドレット使える所を外部コマンド使うなよとは思うね
出力から値をテキスト抽出で取り出すとかもエレガントではないな

あとlsとかcatとかdirとかのコマンドエイリアス使うのも微妙に感じる
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況