PowerShell -Part 6
レス数が1000を超えています。これ以上書き込みはできません。
>>1
BathyScaphe利用開始記念書き込み
乙 今までコマンドプロンプトを使っていましたが、windows power shellに乗り換えました。
コマンドプロンプトでは、エクスプローラーからドラッグ&ドロップでファイルパスが入力できましたが、
windows power shellではできませんでした。
ファイルパスを楽に入力する方法はないんでしょうか ドラッグ&ドロップを扱うのはコンソールの仕事なんじゃ?
conhostで試してみたけどcmd/pwsh/windows powershellどれでもいけた
あんまり設定弄ってないはずだけど、左上クリックして出てくるメニューのプロパティからコピペ関連の項目があるので触ってみては
wtで試すと何れのシェルでもファイルのD&Dは受け付けなかった、異常に高機能なのに意外
wtのことならwtスレで聞くといいかと 追伸
wtはexplorer上でファイルをコピーしてctrl+[shift+]vでペーストするとファイル名が入力される
D&Dにこだわる理由がないなら慣れた方が早そう、労力は大して変わらないだろう >>6-8
power shellはwindowsボタンを右クリックして起動するやつを使いました。
今試したら、D&Dできないのは「管理者として実行」する方で、通常モードならD&Dできました。
管理者モードかどうかで挙動が変わるんですね・・・。 UIPIって仕組みで権限またぎのドラッグアンドドロップは禁止されてるみたいね wtスレってどこだよ
勝手が違うから戻してほしいしこんなの作る前に非コンソールのpowershell出せよ まるでスマホの使い方がわからず店頭でキレて周りに介助してもらおうとするおじいちゃんと同じ言動で草
wtにファイル名をドロップできないのは誤解で、cmdと同じ管理者モード間のOSによるセキュリティ機構のUIPIが原因だった
wtはcmdよりよっぽど癖がない良アプリ
Powershellのほうがよほど癖強い
あとwtは普通に元に戻せる >>10
あれなんでだろうね
打ち直せば入力できちゃうんだしよくわからん >>13
ドラッグアンドドロップという操作が危険だから狙い撃ちで制限されているというわけではなくて、プロセス間のメッセージ通信に対して制約が掛けられた結果ドラッグアンドドロップも使えなくなった >>14
ああ、conhostをadmin専用にしてて、そこから各シェル立ち上げたと思うわ
俺環でテキトーな検証してごめん Allow dragging files or folders into Terminal's Command Prompt window to display their path #12377
https://github.com/microsoft/terminal/issues/12377 前スレの質問者に本当に必要だったものは、たぶんこういうのだと思うんだ…
class node {
[node]$val;
[node[]]$children;
} まちがえた→[object]$val
教えたがりおじさん見苦しい 昔csvdeのエクスポートデータをVBSで木構造に変換したりしたけどその時はジャグ配列でなんとかなった
powershellだと配列に色々罠があるから大変そう
コマンドレット化されてるデータ構造を扱う事は得意でもテキストを1から解析して階層データとして扱うのには向かない気がする 木のテキスト表現がカッコや""等ならbalancing groupでパースするのが便利だよ
perl/Pythonよりdotnetのパターン言語の方が強い(丸パクリだから当然だけど) 組み込み型はスプラッターしちゃうとか罠多いから、内部でキッチリ階層持ちたいなら>>18みたいなロートルな手段が堅牢だったり
仕様覚えるという道もあるけど俺は諦めた 逆説的だけど、.NETに詳しくない俺みたいな人ほどテキスト処理は抑えておくべき
なんか良く分からん物が返ってきても、オブジェクトの印字表現をOut-Fileで捕まえてテキスト処理にフォールバックできる() -match一発でパースが済まない木の表現は、段落を使って木を表現するyamlみたいなやつ
balancing group+複数行マッチで頑張れるかもしれないけど、地道にインデント数えてるわ 一見不器用でもインデントレベルは素直に数えるのが正解
例えばpythonインタプリタもカウンタを使って構文をパースしてる
yaml系のシリアル化フォーマットは、インデントを数えるだけでパーサが書ける移植性が売り Chromeでもパスワードにメモを付けて保存できるようになるみたいね 変数を文字列の中に入れ込んでしまって、消せないフォルダが出来てしまいました
C:\works\+ $a
削除もリネームもフォルダ移動すら出来ません
どうすれば削除出来ますでしょうか?
お知恵を貸してください ファイル名に$が入って、$aが展開されちゃう的な?ならエスケープすればいいだけでは
`$a
意図を汲めてるかちょっと自信ないけど >>28
1. 変数を使ってフォルダを作ろうとした
2. 変数に値を代入した $a = 0225
3. C:\works\0225 を作りたかったので
“C:\works\ + $a” としたかったが
’C:\works\ + $a‘ としてしまった
4. + $a という名前のフォルダが
C:\works\ 直下に作られた
5. エクスプローラからもPowershellからも
+ $a と名前のついたフォルダは削除、リネーム、
移動が出来ない
C:\works\ + $a\test.txt のように+ $a フォルダ内に
ファイルを作る事は可能
Win10 Windows powershell 5.1 VSCODEで作成
細かい所はあまり覚えてませんがこんな感じです うちの環境では削除できた
なんかのプロセスにロックされてるんじゃないの? エラーメッセージを貼らない奴の相手してもしょうがない >>31
これは失礼しました
エラーは下記です。普通の名前のフォルダは削除出来ます
Remove-Item : 引数 '$null' を受け入れる位置指定パラメーターが見つかりません。
発生場所 行:1 文字:1
+ Remove-Item + $a
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Remove-Item]、ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand ちなみにフォルダを右クリックして出てくるプロパティ→セキュリティのタブには
「要求されたセキュリティ権限は利用できないか、または表示されません。」
とのエラーも出てます >>32
> ’C:\works\ + $a‘ としてしまった
んなら
Remove-Item ’C:\works\ + $a‘
ってやれよ… >>34
すみません。。
やってみました
Remove-Item : パス 'C:\works\ + $a ' が存在しないため検出できません。
発生場所 行:1 文字:1
+ Remove-Item 'C:\works\ + $a '
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\works\ + $a :String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand コマンドプロンプトを管理者権限で起動
rd /s /q エクスプローラーから対象フォルダをD&D
これで無理なら排他制御キャンセルするソフト使うかPCを一旦再起動 >>35
> Remove-Item : パス 'C:\works\ + $a '
$a の後ろの空白 >>36
ありがとう御座います
「指定されたファイルが見つかりません」
と返されました。再起動も状況変わらず
Dirコマンドでは+ $a は表示されておりエクスプローラでも見えてるのですが何故か認識されないです コマンドで消したいだけならワイルドカードやタブ補完で選択すればいいじゃない
再起動後エクスプローラーから消せないか試したの?
何がしたいのか分からん >>37
空白で思い出しました
試行錯誤してて
'"C:\works\' + $a + '\"'
のような事もやってました
なので(なのかどうかも分かりませんが)フォルダの名前には + $a と後ろにも空白が入っています >>39
エクスプローラからの削除だと削除後も+ $a フォルダが残り続けます
やりたい事: + $a フォルダを削除したい 追記正確なフルパス名
[]は半角スペースです
C:\works\[]+[]$a[] その親フォルダにカレントディレクトリを移動して他に$付くフォルダが無い、或いは削除してしまって良いなら
for /d %a in (*$*) do rd /s /q "%~a" もし>>43で駄目だったら最後のとこ
"%~sa"
を試してみて >>43
やはり指定されたファイルが見つかりませんと返されました
一旦整理します
目的︰ + $a フォルダを削除したい
環境:Win10, Win PS ver 5.1, Vscode 1.64.2
記述:'"C:\works\"[]+[]$y[]+[]"\"' (かなり記憶が曖昧)
フルパス C:\works\[]+[]$y[]
※[]は半角スペース
1. エクスプローラ
1.1 右クリック削除→削除後もフォルダが残り続ける
1.2 リネーム→「この項目は見つかりません。次の場所にはありません。」
1.3 移動→同上
2. PS
2.1 Remove-Item(\works直下)→「引数 '$null' を受け入れる位置指定パラメーターが見つかりません。」
2.2 Remove-Item(フルパス)→「 パス 'C:\works\ + $a ' が存在しないため検出できません。」
3. CMD
3.1 rd /s /q→「指定されたファイルが見つかりません」 >>44
saでも変わらずでした
>>45
>>46の1.1と同じでした フォルダが消したいだけならPowershell関係ないからこちらでどうぞ
Windows 10 質問スレッド Part82
https://mevius.5ch.net/test/read.cgi/win/1644831539/ >>47
> 上記 $y → $a です
> すみません
だからさあ、入力した内容とエラーメッセージをそのまま貼ってくれよ… dir "*a*" などとして対象のフォルダだけ表示されることを確認して
dir "*a*" | dir "*a*" | % {remove-item -LiteralPath $_.Name}
でどうだろうか dir /x
で8.3形式のファイル名があるなら、それで消してみる
だめなら、>>50の形式でフルパスを指定する ありがとうございます。
レス遅くなりました。以下のように返ってきました。
>>53で出てきたフォルダ名+[]$aと末尾に半角スペースが見えません。
見えない文字が埋め込まれている可能性はありますでしょうか?
>>52
dir : 項目 C:\works\ + $a が見つかりませんでした。
発生場所 行:1 文字:1
+ dir "*a*"
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\works\ + $a :String) [Get-ChildItem], IOException
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
>>53
dir : 項目 C:\works\ + $a が見つかりませんでした。
発生場所 行:1 文字:1
+ dir "*a*" | %{remove-item -LiteralPath $_.name}
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\works\ + $a :String) [Get-ChildItem], IOException
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand >>54
ドライブ C のボリューム ラベルは Windows です
ボリューム シリアル番号は AE2C-1EB8 です
C:\works\ のディレクトリ
2022/02/23 16:50 <DIR> + $a
2022/02/25 10:55 <DIR> .
2022/02/25 10:55 <DIR> ..
0 個のファイル 0 バイト
3 個のディレクトリ 1,144,323,043,328 バイトの空き領域
>>50
使い方が分からず試せてません Win10の質問スレ行けって言ったのに何故行かないのかな?
powershellに拘る理由がわからないよ
仕方ないのでこっちで回答するわ
Poweshell関係ないけど
https://itojisan.xyz/パソコンのトラブル/windows10でフォルダ・ファイルを削除できない/
これ全部試せ これ本来含まれないはずの+が含まれてるから消さないんでしょ
ディスクエディタかなんかで強制的に消せる名前にリネームするしかないのでは?
(FAT時代にしかやったことないからNTFSでできるかは知らん)
曖昧な記憶のスクリプトを正確に思い出せればなんとかなるやもしれんが
普通の方法では+がファイル名かフォルダ名の一部と解釈されないから消すのは無理だと思う
なかなかコーナーケースのバグ見つけたなw
多分PSでどうこうできる領域じゃない
再インストールが一番早いかもw 当てずっぽうで試す前に、まずabout_Quoting_Rulesを読んでくれ
何かおかしい文字が入ってるのかは、[byte[]]にキャストすれば分かるから
それ見て正しくクオートして入力してくれ >>58
+を特別扱いするのはNTFSじゃなくて、特定のコマンドの仕様では?(copy fi+le等)
色んなコマンドが内部で引いてる可能性があるから避けたほうが無難な文字とは思うけど
$もNTFS的には合法だけど、予約名のプレフィックスにする慣習なので、なので避けたほうがいいのは確か
undocumentedなのもいっぱいある win10/pwsh7.2.0/NTFSで試してみた
> ni -d sandbox |sl
> echo valid? >'+ $a'
> gci |select name
Name
----
+ $a
> ri '+ $a' &&echo $?
True
> gci |select name
# no output
うーん? cmdを起動して
rd "\\.\C:\works\ + $a " ダメなら引用符ありなしと、//./ と //?/ を変化させて試してみて 検証した
cmdを起動して rd "\\?\C:\works\ + $a " が正解だった
このやり方はPowershell経由では消えない
末尾スペースが再現できなかったから md "\\?\C:\works\ + $a " で作った >>62
>>64
消えました!!凄い!!!
ご教示頂きました皆さん本当にありがとうございます! 因みに rd “\\?\〜“ってどんな意味でしょうか? ずこー
ファイル名に末尾スペースはNTFS的に非合法のはずなのに、なんで作れちゃうかな
闇が深い 一応補足しとくとシェルは関係ない、pwshから非合法パス名へアクセスするのにも(ri)Remove-Item "\\?\~"は使える(使えてしまう) ri -lp '\\?\C:\Users\ore\sandbox\trailing 'で消せた
そもそも-literalpath指定無しには正しくない名前のファイルは作れないようになってる
標準のFileSystemプロバイダは静かに切り詰めるようだけど、できればエラーにしてほしいところ 当たり前だがext4上では合法だから普通に作れるな
プロバイダ依存きをつける 各々のプログラムのモラルに任せられてるのが残念なところ
pwshからコマンドレットを使う限りはうっかり変なもの作るの阻止してくれるのが救いか
linux/mac上ならそもそもOSがハネてくれるのでpwshで余計なチェック挟む必要もないのだけど Mac特有の濁点ユニコードもそのまま入るし互換性のためだろう いや
>>29によるとコマンドレットで作れてしまったのか
それはちょっとまずい気がする いや真似しても普通には再現できなかったよ
\\?\ でなんとか作った
条件もわからんしいたずらに憂いてもしょうがない APIで普通に作れるから対策したつもりてもコマンドを適当に組み合わせたら偶然できるようなレベル
web上に消し方の情報が沢山あるのはそういう理由 そりゃあえて迂回したらな
Test-Path -IsValidは信頼できるのだろうか?
中身分からものに頼るよりendswith(". ")とかで自分でバリデーションするべきか 任意文字列渡されてもそのまま作らせない、あるいは勝手に置換+ユニークIDにリネームが現実的な防御策か
ファイルシステム移行で問題起こす事もあるし、どこでも合法なファイル名に正規化しておいた方が後のため >>79
ID変わってるけど64と78は同一人物です
psを普通に使う範囲までこのOSの瑕疵を気のするのは過剰品質だと感じるし、日本の安心安全神話で生産性クソ低い件を連想してしまう bashとか平気で不正ファイルポンポン作るからヤバい
OSが拒否するのを期待してるからそれ自体が悪い訳ではないのだが、安易にwindowsで使うのは本当にヤバい win版のgitに付いてくるの使ってるけど、unix系ツールはファイルシステムに気を使う移植は見たことがない
仮想ドライブに隔離してしまうのが手っ取り早くて安全そう >>82
これな
考えれば考えるだけボロが出てくるし思考放棄することにした
行儀悪いプログラムの後始末のやり方だけ知っときゃいいのよ
(真剣な仕事でなければ) win11ではこっそり治ってたりしねーかなこれ、なければwin12に乞うご期待… >>82
これは瑕疵ではない、仕様とMSは一応言ってるんじゃね?
>>67によると ↓ だそうだから、自分でちゃんとチェックしろ、対処しろということだろうし
ファイル i/o の場合、 \ \ パス文字列の "? \ " プレフィックスは、すべての文字列解析を無効にし、その後に続く文字列をファイルシステムに送信するために、Windows api に指示します。
↑こう書くのはおそらく他OSのコードをそのまま移植しやすくするため、なんでね?
つまり何もチェック(今回の例なら末端にスペース入ってないか)せずにAPIに渡すと
結果として>>29のようなことが起き得ると あ、>>29では>>64の書式では書いてないのか
>>64の動作は仕様だと思うけど>>29でなったのならバグだな(試す気はない) powershellで文字コード?順でソートしたい時どうしたらいいんでしょう
3---t.txt
3-1-t.txt
4---t.txt
4-1-t.txt
ってファイルがある時、'-'が0x2dで'1'が0x31だから、
3---t.txt
3-1-t.txt
4---t.txt
4-1-t.txt
と並ぶのを期待したのに昇順でソートしたら
gci | sort
3-1-t.txt
3---t.txt
4-1-t.txt
4---t.txt
になってしまう
今確認したらcmdのdir /ONオプションでも同じだった ファイル名の末尾の英字取って
3---.txt
3-1-.txt
4---.txt
4-1-.txt
としたら
3---.txt
3-1-.txt
4---.txt
4-1-.txt
になったけど意味が判らない
変なバグに遭遇した気分 最近のWindowsは9.txtの後ろに10.txtが並ぶように数の大小を考慮したソートを標準で行うからそのアルゴリズムが生む微妙な綾じゃね
レジストリによって挙動が変わるはず
文字コード順を順守させたいならファイル名標準のソートにならないように、ハッシュテーブルの引数なんかを使って単なる文字列としてソートしてあげればいいんじゃないかな テストしてないし遅い気がするけど
下準備なしがよければ
gci | sort {[Text.Encoding]::Unicode.GetBytes($_.Name) | %{'{0,3}' -f $_}}
※Shift_JIS基準がよければ
gci | sort {[Text.Encoding]::GetEncoding('shift_jis').GetBytes($_.Name) | %{'{0,3}' -f $_}}
重複ないなら
$list = [Collections.Generic.SortedList[string,IO.FileSystemInfo]]::new([StrintygComparer]::Ordinal)
gci | %{$list.Add($_.Name, $_)}
重複あるなら
$list = [Collections.Generic.List[IO.FileSystemInfo]]::new()
$list.AddRange([IO.FileSystemInfo[]]@(gci))
$list.Sort({Param($a, $b) [StringComparer]::Ordinal.Compare($a.Name, $b.Name)}) >>89
PowerShell 5.1だと確かにそうなるけど
PowerShell 7.2.1だとgci | sort で期待通りの結果になったよ
最新バージョン使った方が良いんでない? PowerShellでSQliteのデータベースに追記操作しようと思っていますが
テーブル名を変数にし、カラムと追記したい内容を配列で操作しようとすると上手くいきません。
一括で出来ないなら配列内ループでと思いやってみましたが、そちらもうまくいきませんでした。
配列でINSERTするには、以下のサンプルだとどういった記述をすればよいのでしょうか? using namespace System.Data.SQLite
Set-StrictMode -Version Latest
$ErrorActionPreference = "STOP"
# モジュールのインポート
Import-Module SQLite
# データベースファイル
$db_path = "E:\ps1\sqlite\sample.db"
# コネクションオブジェクトの生成
$con = [SQLiteConnection]::new() | % {
$_.ConnectionString = ("Data Source = {0}"-f $db_path)
$_.Open()
$_
}
$cmd = [SQLiteCommand]::new()
$cmd.Connection = $con $Table = "List"
$ArrCol = @("No","Name","Gender")
$ArrRecord = @("1","山田","男") # レコードの追加
$cmd.CommandText = @"
INSERT INTO $Table ($ArrCol) values ($ArrRecord)
"@ どこでどんなエラーが出てるのか分からないし試してないけど
文字列の中で配列変数をそのまま展開してるのが原因なんじゃないかな。
$cmd.CommandText = @"
INSERT INTO $Table ($($ArrCol -join ', ')) values ($($ArrRecord -replace '^|$', "'" -join ', '))
"@
※余計なお世話だろうけどインジェクション対策がないので必要なら入れてね。
(SQLiteがサポートしてるか知らないけど通常はSQLパラメータを使用。) >>99
ありがとうございます。
一回やってみます すみません、色々試したのですがわからずまた質問させてください
$Table = "2022"
$ArrCol = @("No","Day","Name")
$ArrRecord = @("1","2022/03/03","山田")
だとして cmd.CommandText = @"
INSERT INTO "2020" ("No","Day","Name") values ("1","2022/03/03","山田")
"@
だとエラーなくデータベースに追記出来るのですが $cmd.CommandText = @"
INSERT INTO [string]$Table ("No","Day","Name") values ("1","2022/03/03","山田")
"@
だと"0"個の引数を指定して"ExecuteNonQuery"を呼び出し中に例外が発生しました"SQLite error near "2022":syntax error" あと
$cmd.CommandText = @"
INSERT INTO "2022" ($($ArrCol -join ', ')) values ("1","2022/03/03","山田")
"@
か
$cmd.CommandText = @"
INSERT INTO "2022" ("No","Day","Name") values ($($ArrRecord -replace '^|$', "'" -join ', '))
"@
だと
"0"個の引数を指定して"ExecuteNonQuery"を呼び出し中に例外が発生しました"SQLite error near "/":syntax error"
とエラーが出てデータベースを変更できませんでした
色々試したのですが理由がわからず申し訳ございませんが教えたもらいたく すみません
5chだとSQL関係で書き込めなかったのですが
$cmd.え(E)xecuteNonQuery() | Out-Null
も各場所で記入しています SQLをデータベースに渡す前に、ヒアドキュメントがどう変数展開されているのかデバッグしたりコンソール出力してみるといいよ
いろいろミスに気づくはず
軽く見た感じ次のように展開されてる気がする
INSERT INTO [string]2022 ("No","Day","Name") values ("1","2022/03/03","山田")
INSERT INTO "2022" (No, Day, Name) values ("1","2022/03/03","山田")
INSERT INTO "2022" ("No","Day","Name") values (1, 2022/03/03, 山田) PowerShell and OpenSSH team investments for 2022
https://devblogs.microsoft.com/powershell/powershell-and-openssh-team-investments-for-2022/
We continue to explore and discuss with the Windows team how to make it easier to deploy PowerShell 7 on Windows.
As noted previously, support lifecycle differences between Windows and .NET along with size constraints we don’t have the ability currently to ship PowerShell 7 in Windows.
Previously we considered a bootstrapper to be a viable solution giving the experience of being inbox in Windows, however, it would have been a significant effort to implement.
Instead, we are exploring shipping a cmdlet in Windows PowerShell to make it easy to install PowerShell 7.
A new RFC will be published to discuss this. >>92
1つ目の例のUnicodeはUTF-16LEの事だからだめだったね。
BigEndianUnicode(UTF-16BE)にする必要があったし、
そもそもbyte型にしてエンディアン気にする必要もないから、
gci | sort {[int[]][char[]]$_.Name | %{'{0,5}' -f $_}}
でよいはず。
※全く関係ない別の作業中になんか急に気づいた。 SQLiteがカラム名等を「"」で括る事を要求しているなら
$cmd.CommandText = @"
INSERT INTO "$Table" ($($ArrCol -replace '^|$', '"' -join ', ')) values ($($ArrRecord -replace '^|$', '"' -join ', '))
"@
かな。>>106さんの言う通りなので確認してみて。
これもだめなら、成功例と、失敗例や変数値のテーブル名が違うからそこかも。 >>107
もう開発やめりゃいいのにな
これまでWindowsに入ってるから採用されてきただけで、わざわざ入れて使うならPowerShellなんか選ばれるわけがない
コマンドレットで簡単に導入できるようにするならPowerShellじゃなくてPythonにでもしたほうがいいんじゃないか インストールしてなくてもpythonコマンドでMSストア版pythonのダウンロードページに飛ばされるから、既にpwsh7よりも導入が楽という悲しみ PowerShellってそんな残念なプログラム言語なんですか?
がんばって勉強したのに納得できません PowerShell5系は向こう10年は大丈夫
6以降はAzure以外では全く使われておらず、Azureに生涯を捧げるのでない限りは完全無視でOK メインは蛇使いだけど
色々インポートしなくてもそこそこ戦えるのでregex、小規模データ処理、重くない数値計算がシェルから直接引けるpwshは有り難い
ネイティブライブラリ揃ってないからパワーが居るのはPython、まあPython自体はpwshとドングリ背比べ(処理速度、標準ライブラリもほぼ等価)だけど、やはりライブラリが強い PowershellとPythonだと得意分野が違うよね ちょっと詳しい人に聞きたいんだけど開発環境で使用しているSDKのコマンドがcmdだと実行可能だけどPowershellだと一切認識されませんてエラーがでるんだけどこの理由はなぜ?
WIndows 11だとターミナルのデフォがPowershellなのにもやもやする、この解決方法はある?
もう一つ、ファイル名を指定して実行で起動したcmdからはSDKのコマンドが実行できるのに、Terminal(wt.exe)の既定のcmdからコマンドを実行すると認識されていませんエラーが出るんだけどこの原因もなぜ?解決方法はある?
cmdとpowershellとterminalと複数のshellを用意してMSは何がしたいのかマジで意味がわからない
WSLとか作っててOSSに寛容になったんだからさっさとデフォのShellをbashかzshにしてくれれば開発環境としてより便利なのに・・・ しかもそのデフォルトで開くPowerShell、既に非推奨のバージョンなんだぜ
もう完全に破綻してるからWSLだけ使えばいいのよ >>118
情報少なくてわかんないけど、カレントフォルダに対して「.\ファイル名」の記法で書いてないとかはない?
ファイル名に特殊記号を含むとか bashとかは言語的にはPowershellに比べて時代遅れ過ぎるわ
さっさとPowershell7に統一したほうが遥かにマシ 10や11に標準で入ってる5.1で動くようにしてる人が大半じゃないの
機能的にも特にこれ以上期待するものはないんだけど >>119
いやマジでそれでしたwww
PS7をインストールしてPS7で実行したらCLI認識しましたイミフwww
そしてPS7をインストールしてもアップデートされずWin11デフォのPS5がそのままアンインストールもできず鎮座してるくそすぎて草 >>106
デバックで出力したとき文字列だから勝手に"が消されているものかと先入観を持ってしまっており疑問にすら思いませんでした
丁寧に説明していただきありがとうございます。
>>109
ありがとうございます。明日確認してみます。 powershell.exeに-Fileで.ps1スクリプトを指定する場合に、
引数で文字列配列を指定する簡単な方法はありますか?
.ps1側に変更を加えるのは無しで、Param()は以下の指定だとします。
Param( [string[]] $p1, [string[]] $p2 )
普段はPowerShellコンソールや他のスクリプトからこの.ps1を使っています。
これを.batに組み込みたい事があったものの配列の指定方法が分からず、
以下のように-Commandにして回避しました。
-Fileの場合でも指定方法があったのかな、と気になっています。
powershell.exe -c "〜.ps1 -p1 @('aaa', 'bbb') -p2 @('ccc', 'ddd')" $Table = "2022"
$ArrCol = @("No","Day","Name")
$ArrRecord = @("1","","")
このようにブランクの配列があると
'1', ', ','
上のように途中の「""」が「'」シングルクォーテーション1つになりエラーが起こっているということがわかりました。
ですので
$ArrRecord | foreach-object -Process {$_ -replace '"',"'"}
として配列内で変換しようと思ったのですが、$_の時点でダブルクォーテーションが取れており上手く変換できない状態です
($($ArrRecord -replace '^|$', '"' -join ', '))の「'^|$'」は正規表現で前と後ろを「"」で変換するということですよね
途中のパイプの意味がわかっていないです >>126
苦戦してるね
まずプログラミング一般の基礎として、ソースコード上に文字列型の変数値を直接書きたいということを伝えるための(文字列リテラルの)引用符と、文字列の中に引用符という文字データを含めたいと伝えるための引用符は別なので理解・区別しておかないとずっと混乱する
$_の時点で引用符が取れたという感覚は間違いで、今回文字列の中身には引用符文字は含まれていなくて、文字列リテラルですと伝える引用符になってる
次に、^|$ で置換する発想は、文字列の特定の位置が先頭または末尾なら置換というところまでは狙いどおり
でも空の文字列だった場合、正規表現処理が文字列を左から走査したとき「先頭かつ末尾」という単一の位置しかないので、置換も一回しか行われず引用符一つだけになるというバグになってる
例えばこうすれば文字列リテラルのなかに引用符文字を入れられる
($("""$ArrRecord""" -join ', '))
($("`"$ArrRecord`"" -join ', '))
($("'$ArrRecord'" -join ', '))
いずれも外側の二重引用符がリテラルの引用符で、内側の引用符が文字データの引用符 >>127
配列じゃなくて各要素の文字列を囲まないとダメたった
($("""$_""" -join ', '))
($("`"$_`"" -join ', '))
($("'$_'" -join ', '))
あと正規表現のパイプは「または」という意味 PowerShellのバージョン問題はwslに最新のpowershellを入れるでok? >>129
Linux版Powershell7はWindows版Powershell7と比べて機能制限も多い
よって全く解決しない LinuxでPowershell使う理由なんてあるか?
bashの方が明らかに上だろ > bashの方が明らかに上だろ
確かにバカをあぶり出す能力は高いなw >>131
Linux版使った事ないから
bashとどう比較してるか興味あるよ
優劣を列挙しもらえると助かる powershellはC#埋め込んでそこで定義したクラスとかがpowershellで使えるとこがいいところだから
bashもそうしたらいいとおもう コマンドレットの出力がオブジェクトで目的のプロパティから値が取り出しやすい
Where-object一つ覚えればフィルター出来るからコマンド毎にフィルタの仕様で悩む必要が無い
正規表現がperl拡張表現で標準搭載、コマンドやら環境によって規格が違うとか悩む必要がない
シェルスクリプトとしてそれだけでも全然いいわ regex沼に入る気はないけど$matches.namedで参照できるだけでもかなり有り難い
pwsh固有の事情としては(?-i)を繁用するな
sls等コマンドレットに-CaseSensitive渡したり-[ci]matchが入り乱れてたのがスッキリした あとStringとString[]どっちも渡ってくるから(?m)/(?-m)もpwsh的には重要か >>128
レスの内容を色々と検索しながら勉強させていただきました
まだエラーが出て止まっていますが、こちらで少し対応を考えてみたいと思います
本当に丁寧に教えていただきありがとうございます 二つの引数をとる関数に引数を二つ渡したら、一個目引数が全部持っていくのはなんで?
コード
function war {
param($putin, $zelenskyy)
Write-Host 'putin has ' $putin
Write-Host 'zelenskyy has ' $zelenskyy
}
war('Russian','Ukraine')
結果
putin has Russian Ukraine
zelenskyy has >>141
配列
@(
"aaa"
"bbb"
)
の別表記がカンマ区切りリスト
"aaa","bbb" 格好も括弧も関係ない
シェルなんだから引数の区切りは空白と言うだけの話 war Russian Ukraine
にしろっつーことでしょ? 失礼、こうだね
war ‘Russian’ ‘Ukraine’ Set-StrictMode -Version 2.0 おすすめ
https://docs.microsoft.com/ja-jp/previous-versions/dd347614(v=technet.10)#%E4%BE%8B-2 赤文字で出るエラーメッセージをログに出力して、
エラーログが出てるか適当な箇所で判定して、ログをnotepadで開くってことをやりたいです。
標準エラー出力みたいなのの取得方法を教えて下さい いくら補完あると言ってもコマンドレットの名前冗長すぎんだよ 長いから分かりやすくていいんだろ
wとか言われてもユーザーを笑いものにするコマンドか?としか思えんし 配列の配列について
$array_of_array = @(
@(
'1-1'
'1-2'
'1-3'
),
@(
'2-1'
'2-2'
)
)
$array_of_array | foreach {
Write-Host 'L1' $_
$_ | foreach {
Write-Host ' L2' $_
}
}
結果は期待通り
L1 1-1 1-2 1-3
L2 1-1
L2 1-2
L2 1-3
L1 2-1 2-2
L2 2-1
L2 2-2 だが、カンマを省略すると
$array_of_array = @(
@(
'1-1'
'1-2'
'1-3'
)
@(
'2-1'
'2-2'
)
)
結果は期待と違う。配列の配列じゃなくて、ただの配列になっている?
L1 1-1
L2 1-1
L1 1-2
L2 1-2
L1 1-3
L2 1-3
L1 2-1
L2 2-1
L1 2-2
L2 2-2 改行してカンマをいれると
$array_of_array = @(
@(
'1-1'
'1-2'
'1-3'
)
,
@(
'2-1'
'2-2'
)
)
後半だけ、配列が要素になっている?
L1 1-1
L2 1-1
L1 1-2
L2 1-2
L1 1-3
L2 1-3
L1 2-1 2-2
L2 2-1
L2 2-2
どういうことなのか教えてよ。 powershellで配列データ構造を扱ってはいけない >>153-155
あまり自信はないのですが、
・「単項の ,」と「配列要素区切りの ,」は別物です。
(「-1」と「1 - 1」の「-」が別物、みたいな違い。)
・式の終端と見なせる箇所にある改行は「;」と概ね等価です。
>>153の「,」は「配列要素区切りの ,」です。
>>155の「,」は「単項の ,」です。 ワンライナーにするとこんな違いがあります。
>>153
@( @('1-1'; '1-2'; '1-3';) ,@('2-1'; '2-2';); )
>>154
@( @('1-1'; '1-2'; '1-3';); @('2-1'; '2-2'); )
>>155
@( @('1-1'; '1-2'; '1-3';); ,@('2-1'; '2-2';); ) 追加。
Out-*やWrite-*で出力先が示されていない改行や「;」などは、
暗黙のWrite-Outputが動くと考えるとよいです。
つまり「@(〜);」は「Write-Output @(〜);」となり、この時、配列が1段階分解(要素取出)されます。
ただし「単項 ,」の「,@(〜)」は「Write-Output -NoEnumerate (,@(〜))」となり、分解されません。
イメージ的にはこんな違い。(本当は他にもWrite-Outputが入ります)
>>153
@( (Write-Output @('1-1'; '1-2'; '1-3';), @('2-1'; '2-2';)); )
>>154
@( (Write-Output @('1-1'; '1-2'; '1-3';)); (Write-Output @('2-1'; '2-2';)); )
>>155
@( (Write-Output @('1-1'; '1-2'; '1-3';)); (Write-Output -NoEnumerate (,@('2-1'; '2-2';))); ) 暗黙のWrite-Output
コマンドレットのような何某かの出力を持つものと、Powershellのスクリプト内で定義された関数や式の評価結果を
うまいこと混ぜることが出来るようにする仕掛けなのでしょうか
完全に理解しては居ませんがが、理解に努めます
文法知識は「Windows PowerShell実践システム管理ガイド 第3版(日経BP)」の第2章を読んだだけなのですが
これだけは全然足りないtのを痛感しました
何かお勧めはありませんか powershellは行志向寄りの言語だから改行はC/C++でいう暗黙の副作用完了点みたいな意味を持っている
何も考えず複数行にまたがる式を書くと思わぬ事故に繋がるから、C/C++の\やVBの_みたいに行継続を示す`を行末に付けるといいよ
$array_of_array = @( @('1-1', '1-2', '1-3') `
, @('2-1', '2-2')) >>161
今回の挙動の予想や理解は、構文のパース(式・文の区切り)、
独特なパイプラインの挙動、分かりづらい「単項 ,」の存在などがあり
わりと難易度の高いものです。
>>156、>>162さんに同意で、配列の配列(ジャグ配列)を避け
行の継続を「`」で明示する事をお勧めします。
書籍では『Windows PowerShell イン アクション』がお勧めです。
ただv1の本なので今となっては内容が古く、紙だと新品の入手が難しいです。
※これのv5以上版が日本語で出て欲しい…。
https://www.sbcr.jp/product/4797337362/
あとは>>157のMSのサイト等。
about_*も有用な事が書かれてますが、日本語訳やサンプルコードの質が酷く、
多くの人がよく使う機能と一部の人が稀に使う機能が同じ扱いの記述なのが難点。 Powershellの洋書翻訳はもっと盛んになってほしい
オライリーのクックブックも原著は改定4版まで出てるのに日本語は初版のままだし 今時英語できないの日本人だけだからな
土人とか馬鹿にしてる韓国、中国、インド、ベトナム、フィリピンなんてネイティブレベルで英語できるからな
これで日本のレベルは低くないとかそれ以前の問題だよ エリート層は英語できるだろうよ
馬鹿は海外だと底辺でも英語ペラペラだと思ってやがるが 日本ですら母国語での情報の鮮度が落ちるんだから
それらの国のプログラミング学習希望者は
必然的に英語の勉強からしないといけないだけの話じゃないかな?
日本のレベルが低いとか
英語できるのはエリート層だけとか
そういう問題じゃないと思いますよ
アニメ理解したいから日本語勉強しましたと
同じレベルの話な気がする まとめて挙がってるけど国によって差は大きい
インドとフィリピンは英語が公用語で世界でも有数の英語話者が多い国
日本の英語力が低すぎて世界に遅れを取っているというのは同意
学校教育も都度見直されてるしそのうち改善されるんじゃねーの、知らんけど
プログラマーなら英語を読むだけでもできるように少しずつ学ぶ気概は欲しい
ボク英語わからないんですと幼稚な変数名を付け続けるのはよくない 日本は国内に金と仕事があるせいで海外でなくても稼げるからなあ
英語理解できなくても儲かる職業の筆頭が
マスコミと教育と役人政治家の時点で英語教育が変わるわけ無いじゃん ITに限定すると英語は必要なんだけど英語に限らず日本のITエンジニアの多くは勉強しない
能力を伸ばしても給料が上がらず残業が増やされるだけと諦めるのが常態化している 国内に金があるというのは微妙な話になってきている
世界ワースト級の低成長による沈下を続けていて、本当に有能なエンジニアは海外に流出して残るのはIT土方ばかり
ノーベル賞受賞者が元日本人ばかりというのと同じような話が起こってる
GAFAのようなIT企業が伸びないから低成長から抜け出さない負のスパイラル 海外ならGAFAみたいな企業がたくさんあるとでも思ってるのかこのゴミは
GAFAは世界中でも1つしか無いんだよ GAFAはひとつとな?
MARCHはひとつみたいな哲学かな?
のようなという日本語の意味はわかるのかな? これ使って出来ることってフォルダ弄りファイル弄り設定弄りだけ?
他に出来ることないの? あとは何かプログラムを走らせたり、せいぜいOSの機能を実行するくらいかな
リモートで出来たりするけど、しょせんはローカルに出来ることがリモートでも出来るってだけだな
まだ勉強をはじめたばっかりだけど、そのマシンで出来ないことは出来ないんだなって分かった >>175
bashなんかのシェルとは違って.NETベースだからC#やVB.NETでできることは一通りできるよbashなんかと違ってね
メンテが楽だからあえてpowershellでGUIを作ったりする場合もある 正規表現使えるしWindowsだとわざわざPythonセットアップして使うより楽だし利便性高い気がする >>175
PowerShellは基本的にはWindowsサーバーの管理に使うもの
管理系のコマンドレットが非常に充実している >>177
出来るからって普通はやらんよまともな脳みそしてるならVSCode使う
お前みたいなのが秀丸やEMでコーディングしてるでぇー(ドヤッっイキリ散らかして周りが迷惑する馬鹿そのものだな >>180
VSCodeを使うの意味が分からん
VSCodeでPSスクリプト組むならいいの?
なんで処理系の話でエディタの話になるの? 分かってるくせに…
対面だと「何いってんだコイツ…」とか思いながらも愛想笑いしてそうだな 釣りでしょ
面倒見いい人なら、オマエそれブーメランやんけーて言ってあげたら喜ぶよ この煽り合いもPowershellスキルの一部なんですか? write-sqltabledateで列名は指定できますか?
計算列のあるテーブルでその列を飛ばしたいのですがPsCustumObjectのプロパティ名が無視されて並び順で投入されてしまいます。 >>186
すいません
Write-SqlTableData
でした…
よろしくお願いします そういう挙動ということはWrite-SqlTableDataはメタデータを考慮してなさそうだし
Invoke-Sqlcmdでやれば? コマンドレットの命名規則をケバブケースにしたMSの馬鹿を殺してやりたい
補完でタブ押して確定してまたタブ押して確定してってのがめちゃくちゃイライラする 自分の思い通りじゃないとすぐにイライラしたり殺したくなったりする >補完でタブ押して確定してまたタブ押して確定して
状況が分からん 文字列をPowerShellの文字列リテラルとして出力したいのですが、どうやったら楽ちんに出来ますか?
例えば下記を実行すると
$s = "``i`'`""
function literally {
param ($t)
return $t
}
Write-Output (literally $s)
実行結果は
`i'"
こうなりますが、
"``i`'`""
こうなってくれる function literally は既存の関数にありますか? >>188
ありがとうございます
やっぱそれが無難ですかね
IDENTITYにしたオートインクリメントな列は空文字列の代入で飛ばせたので計算列も何か方法が無いかと思ったのですが… >>193
literally が何を意図してるのかわからんが
単一引用符のヒアドキュメントで囲むとか
$s = @'
"``i`'`""
'@
必要なリテラル部分だけ抜き出したファイルを作成してgcで読むとかすりゃいいんじゃね
あとは必要ならInvoke-Expressionなりして使う
まじめにコード内でエスケープ処理とかやろうとしたら一晩掛かるよ まじめなエスケープ処理を10分くらいでできる関数とかないですか --- ここから x.ps1 ---
function x {
$s = (Get-Content -Path 'a.txt')
Write-Output ('$a = ' + "'" + $s + "'")
}
x | Out-File 'a.ps1'
--- ここまで ---
--- a.txt の中身が ---
im.dat
--- ここまで ---
の場合 a.ps1 は
$a = 'im.dat'
となって PowerShellで読み込める
--- a.txt の中身が ---
i'm.dat
--- ここまで ---
の場合
a.ps1 は
$a = 'i'm.dat'
となってシンタックスエラーになる。こういう場合のためにエスケープ処理をしたいのです。 >>198
であるならば>>195で示したヒアドキュメントを使えばそんな処理は不要になる
function x {
$s = (Get-Content -Path 'a.txt')
'$a = ' + "@'"
$s
"'@"
}
x | Out-File 'a.ps1' a.txt の内容が下記の場合はエラーになります。
'@.dat
----
いまさら気が付きましたが、やりたいことは、
PowerShellスクリプトをPowerShellで出力したいので、文字列をエスケープしたい。
最初から、こう言えればよかった。 >>200
そういうのも想定するなら'@で分割して結合するだけ
これで穴の無さそうなエスケープ処理相当にはなったかな
function x {
$s = Get-Content -Path 'a.txt'
[string[]]$t=$s -split "'@"
for ($i = 0; $i -lt $t.length; $i++) {
if ($i -eq 0) {
'$a = ' + "@'"
} else {
'$a += ' + "`"'@`""
'$a += ' + "@'"
}
$t[$i]
"'@"
}
}
x | Out-File 'a.ps1' 文字列リテラルの構文仕様を見るかぎり、
function ConvertTo-StringLiteral ([string] $s) {
'"{0}"' -f ($s -replace '[$"\u201C-\u201E`]', '`$&')
}
でいいのでは。
function x {
$s = Get-Content a.txt
'$a = ' + (ConvertTo-StringLiteral $s)
}
みたいに使う。 >>201
普通の「'」以外のシングルクォート類(*)も、正当なシングルクォート文字なので、
a.txt に「‘@.dat」とか入力されるとエラーになる穴が...。
(*) U+2018、U+2019、U+201A、U+201B >>202-203
非常に勉強になったよ
ありがとう >>202
https://www.microsoft.com/en-us/download/details.aspx?id=36389
これを見つけたので 22ページあたりを読むと、シングルクォートで囲む verbatim-string-literal は、割とシンプルで
single-quote-character(普通のシングルクォート+4個) を含む場合に single-quote-character single-quote-character とするので
function ConvertTo-SingleQuotedStringLiteral ([string] $s) {
"'{0}'" -f ($s -replace "['\u2018\u2019\u201A\u201B]", "'$&")
}
こうすればいいのだろうか? 何でインデントついてるんだろと思ったら\u3000でしたか >>205
うん。範囲指定できるので、"['\u2018-\u201B]" とか書くと、もっとシンプルかも。
>>206
U+3000 の Unicode クラスは Zs で、正当な空白文字なので、コピペで動いてくれる。 >>1
$url=$($site="+pj.og.ldn.iakkokA3%etis=q?hcraes/moc.elgoog.www//:sptth".ToCharArray();[Array]::Reverse($site);-join $site)
"ソビエト人","支那人","朝鮮人" | % {start "$url$_";sleep 21} (Get-Date).ToString("M/d") # 4/7
(Get-Date).ToString("M") # 4月7日
(Get-Date).ToString("d") # 2022/04/07
"M"と"d"単体で取れないのは仕様なの? 事務員がこれ使って自動化して評価されるかね?
Excel VBAとかだと認知されてるし動きも分かるからアピールになりそうだけど、これはps1をダブルクリックしたら既に結果が出てるキンクリ状態になるんで何か地味なんだよね
出来ることは多彩なのにさ キンクリ状態てどういう意味なん
例えばExcel操作の自動化なら最初に$excel.Visible = $true
とでもしとけば同じようにリアルタイムで処理中の動きが出てくるけど
事務員ならいらん仕事押し付けられるのがオチだから隠しとけ
この程度でドヤりたいならIT土方にでも転職しなよ 事務員がマクロやスクリプトで評価されても給料や時給が上がったりはしないだろ
都合よく使われるだけだよ
退屈な定常業務から抜け出したい動機なら良いのかも それがパワー・シェルの能力……
ボクがこのps1をダブルクリックした時点で"結果"はもう確定しているッ!!
マクロみたいなトロいもんじゃあないんです やっぱり評判あんま芳しく無いからやめとくわ
回答してくれた皆さんありがとう >>220
ダブルクリックしたらISEが開いたんだが パワーシェル
破壊力 A
スピード B
射程距離 A
持続力 B
精密動作性 E
成長性 E
タイプ 自動操縦型
能力 人が嫌がる仕事をする
To Be Continued… パワーシェルのスピードは最下位ランクだろ
C#埋め込むなら別だが Cランクが人並みだからそれよりちょっと速いBランクが妥当 windowsに標準に入っているってことだけはかなり優遇されてる プログラミングにおける認知度の低さは調べにくいし致命的 プログラミング言語の人気ランキング、順位変動は縮小傾向にある――RedMonkが調査
https://atmarkit.itmedia.co.jp/ait/articles/2204/13/news040.html
このランキングだとPowerShellは17位だぞ
Rustに勝ってる! PowerShellはランキングとか関係ないでしょ
PS5止まりで.NET4.8と心中する運命しかない、完全に袋小路の言語だよ Windowsと共に来たりWindowsと共に滅ぶべし >>232
おれがこれまで作ったソフトのほとんどが共に滅ぶな
かなりの割合の開発者が一緒に滅ぶんじゃないだろうか >>231
それってよく聞くけどなんの問題があるの?
Powershellなんてそもそもbetter MS-DOSであり
better WSHでしかないんだからなんの問題もないでしょ
なんか過剰な期待をしてた人がいるの? そもそもすでにオープンソースなんだし衰退することはあるだろうけど袋小路とか意味わからん Powershellはオープンソースとして元気にやってるよ
7.3でコミュニティ主体の機能改善になりそうなのはこの辺とか?
scriptblockの引数の数でオーバーロード解決できるようにしたいというもの
https://github.com/PowerShell/PowerShell/issues/16940 あとはc言語とかrustのようなネイティブアプリからPowershellをホスト出来るようになっていたりする
https://github.com/awakecoding/pwsh-native-host 元気もなにも開発してるのMSの社員だし、6以降は事実上Azure専用だよ >>237
コードちら見したけど普通にPSプロセス呼んでプロセス間通信した方がよくないってなった >>239
新たにプロセスを立ち上げることでコマンドライン等が生成されるのを回避したいらしい Powershell使えたら小5と付き合えますか? 20年位前の30代前半の頃、小6と付き合ってた
powershellのお陰だと思うよたぶん >>243
そのころpowershellは未だ無いだろ
おれの場合は30年位前に小6と付き合っていると噂されたが事実はそのようなことはなく
当時powershellがあれば付き合えたのは確実だったと思う ワイも小学生低学年のころ、かけっこで1位だった
PowerShellのおかげだろうなあ htmlの特定のID(例:<div id="XXX">)の中身を取得するにはどうすればいいでしょうか?
htmlのソース自体は$sourceに格納しています。 文字コードを文字に変換するコマンドはありますでしょうか。
PS > change-moji -code SJIS 0x41
A
PS >
こういうコマンドです。 >>246
$html = New-Object -ComObject "HTMLFile"
$html.IHTMLDocument2_write($source)
$html.getElementsByTagName("div") | ?{ $_.ID -like "特定のID" }
みたいにCOM使ってDOMで操作するか、正規表現で自力で解析するかしか思いつかない
powershellの定番の処理方法があるなら俺が聞きたい Ruby なら、Nokogiri, CSS Selector で、
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<div>あ</div>
<div id="xyz">い</div>
EOT
element = doc.at_css( '#xyz' )
puts element.content #=> い getElementsByTagName 使うなら getElementById でいいんじゃない Windows11は、結構Powershellが主役の位置に躍り出てきて、コマンドプロンプトの影が薄くなってる。 >>252
DOM操作にお詳しいなら補足してやって
俺は普段webページ解析なんてしないから適当に書いただけなので xml形式ならselect-xmlというコマンドレットがあるんだけどね Invoke-WebRequest でパースできるんだから Web からだけじゃなく html を格納した変数とかもソースにできればいいのにね COMのやつってIEのパーサなんだよね
くやしいけどこの辺を高度にやりたいならスクレイピングに定評のあるスクリプトでやった方がいいと思う $idContents = $html.getElementById($idName).innerHTML
でinnerHTMLを取得して、$idContentsに格納してある「src」の値(src="https://〜〜.jpg)はどうやって取得するのでしょうか? innerHTMLは使わない
getAttribute("src")を使う $idContents = $html.getElementById($idName).getAttribute("src")
で試したのですが、$idContentsの中身は何もない状態です。
試しに、$idContents = $html.getElementById($idName)だけで実行すると、
$idContentsの中身に
innerHTML : <IMG id=img src="https://〜〜jpg/keystamp=〜〜;></A>
はあります。 $idNameは'img'ではなく、'kr3'になります。 だから取得したいのは、id=imgのIMGタグにあるsrc属性値じゃないのか?
$idNameを'img'にしろよ >>264
なるほどです。ありがとうございました。 特定のフォルダの中にファイルが10個以上あったらタイムスタンプが一番古いファイルを削除する処理をPowerShellでどう書くかどなたか教えろください。。
スクリプトはタスクスケジューラで日次で走らせるイメージです。 >>268
一番古い一個だけを削除か、最新の9個を残してそれ以外を削除、の簡単な方でお願いしたいです。 >>270
269の30を9に変更するのが簡単だと思います
一番古い一個だけを消すのは Select-Object -Skip 9 | Select-Object -Last と二回もSelect-Object するのでとても難易度が高いです その質問バッチファイルスレで見たぞ
powershellの回答も貼ってある 【.cmd】 バッチファイルスクリプト %14 【.bat】
https://mevius.5ch.net/test/read.cgi/tech/1597442426/757-764
漏れが763 に、Ruby で書いた。
これをPower Shell(PS)用に書き直せばよい
764には誰かが、PSで書いている フリーランスエンジニアになってからの年収推移を公開【現在年収1000万】
【実体験】仕事ができない新卒エンジニアでも月収70万フリーランスになれる理由
フリーランスエンジニアは年収900万円までは余裕!現役フリーランスエンジニアが徹底解説
フリーエンジニアの平均年収!未経験が年収1000万円を超える方法とは?
月額150万円以上も可能?ITフリーランスで高単価を獲得できる理由
在宅で年収1000万稼ぐフリーランスエンジニアの稼ぎ方【再現できる】
フリーランスのエンジニアやるなら45歳までに貯金5000万円作れないと死ぬ説 フォルダA内にファイルを1つずつ個別に圧縮した上でフォルダBにそれぞれ出力するPowerShellってどう書けば良きでしょうか。
以下スクリプトを書いてみましたが、これだと1つずつの圧縮はできないようで。。。
//フォルダA内のファイル名(拡張子なし)を取得
$src = Get-ChildItem -Name C:\folderA
$file = [System.IO.Path]::GetFileNameWithoutExtension("$src")
//ファイル圧縮とフォルダ移動
Compress-Archive -Path C:\folderA\*.* -DestinationPath C:\folderB\$file >>276
以下のサンプルみたいにForeach-objectとか使ってCompress-Archiveをファイル毎に実行すればいい
$SrcPath = "C:\folderA\*.*"
$DstPath = "C:\folderB\"
Get-ChildItem $SrcPath|
ForEach-Object {$DstFile = Join-Path $DstPath ($_.Name -replace '^(.+)\..+$','$1');$_}|
ForEach-Object {Compress-Archive -LiteralPath $_.FullName -DestinationPath $DstFile} PowerShellで複数アイテムに同じ処理をする場合は、アイテムをリストアップした出力をパイプでForEach-Objectに渡して
ForEach-Object の中で、一個ずつ($_ という変数で参照できる)処理するのが定番と思うの。
get-childitem | foreach-object { write-output $_.fullname $_.name }
とりあえず、これをやってみると感じが分かると思うの。 >>278
ありがとうございます。
ただ、フォルダAにファイル2つ置いて試してみたのですが、いずれも圧縮・移動されませんでした。。。
再度ご確認いただけますでしょか?? ここは労働の場じゃないからな
金のやり取りを伴ってる仕事とは違うのになんでお客様気分丸出しでいられるんだよ >>280
Compress-Archive の使い方(パラメーターの指定方法)は分かってますか?
ファイル一個だけで試してみましたか?
それを調べてから
Get-ChildItem -path "C:\folderA" -File | ForEach-Object {
Compress-Archive -LiteralPath $_.FullName -DestinationPath ("C:\folderB\" + $_.Name + ".zip")
}
これの意味を考えてみてください。 Ruby で、7-zip なら、
a フォルダ以下を再帰的に圧縮して、a.zip アーカイブにする
圧縮
7z a (アーカイブ名) (圧縮したいフォルダ)
7z a sample.zip aaa_folder
archive = "C:/Users/Owner/Documents/test/a.zip"
src_dir = "C:/Users/Owner/Documents/test/a"
# Program Files には半角空白があるので、"〜" で囲む
puts %x("C:/Program Files/7-Zip/7z.exe" a #{ archive } #{ src_dir }) # 圧縮 gciとかの-forceパラメータって必須だろうに
デフォでオフなのがなんだかな わざわざ隠し属性で隠してるのにディフォで表示しろとか頭おかしい foreach中に最後の要素でないって判定どこかでできないですか
これができなくてforに書き直すはめになること何回もあるんですけど…
Foreach-Objectの場合もあったらお願いします 最後の要素でないってどういう目的で知りたいの?
本当に知りたいときもあるけど慣れてない人が書きがちなコードでもあるので気になった
カンマ区切りにするために最後ならカンマを付けない分岐を書くとかそういうの カウンタを用意してforeach対象のコンテナのlengthと都度比較する
これがモダンプログラミング() >>291
次の処理の前準備を現在の要素も使ってやってて最後だけ不要なとき
$i = 0
foreach ($item in $list) {
# $itemの処理
#
if (++$i -lt $list.length) {
# 前準備
}
}
これなら普通にforのが見やすい そういう最後だけ処理が違うってのは同じように処理しといて後から取り除く方が良くね?
二度手間で美しく無いように思えるけれどそれよりも
一々「最後かどうか」の判別に毎回if挿む方がバカらしく感じる >>291
> カンマ区切りにするために最後ならカンマを付けない分岐を書くとかそういうの
そう言うのは最初以外はカンマを頭に付けるようにしたほうがいいかと カンマ区切りしたいだけなら $list -join ',' で十分だな そう、joinで済むんだよね
慣れてない人はフラグや分岐で処理しがち
だからまずは具体的にどんな処理をしようとしてるのか聞きたかったんだ カンマの話は>>291が勝手に言ってるだけなのにjoinですむとかあたおかかよw ID変わってるけど291=298な
判定する必要のない例としてカンマ区切りを挙げて、だから具体的な例を教えてくれと書いたのに、カンマ区切りのうまいやり方をレクチャーしてくれる人が出てきたから説明しただけよ >>294
後から取り消せないこともあるだろう
例えばライトワンスメディアに書くとか 具体的な処理が分からんとどうしようもないだろ
準備じゃなくて、準備のための情報の保存にすることならできるんじゃないか
#itemの準備
#itemの処理
#次のitemの準備のための設定
として実際の準備は次のループの先頭で行うようにする はあ…やっぱり論点ズラしで無いことを正当化する流れになったかw
無いなら無いでいいよ >>289
最初、最後、何番目などには別処理をする場合は、foreachは向いてないというか
もともと for があって、何番目かを気にせず全部の要素に同じ処理をすることが多いので、そういう場合用に foreach があると思ってます >>304
無いことを正当化してる書き込みは見当たらないけどどのレスのこと? だからforeachでは原理的に無理
foreach($item in $items){ ... }
はざっくり
$e = $items.GetEnumerator();
while ($e.MoveNext()) {
$item = $e.Current;
...
}
みたいなコードになるから$e.MoveNext()を呼ぶまで最後かどうかはわからない
極端な話、乱数で最後にするかを決めるような実装されたらどうしようもない 最後の要素って$list[-1]でいいんじゃないの?
if($item -ne $list[-1]){前処理}でいけると思うけど <section id="image-test">
<a href="https://www~BBB.jpg">
<img src = "https://www~AAA.jpg">
</a>
</section>
があって、AAAとBBBのURLをそれぞれ変数にかくのうしたいのですが、これであってます?
$AAA = $web_source_code.getElementById("image-test").getAttribute("src")
$BBB = $web_source_code.getElementById("image-test").getAttribute("href") 合ってないよ
section要素にはsrcもhrefもないんだから取れない
子や孫の要素からイイ感じで取ってきてくれるような期待をしてるんだろうけど、内側がどんな構造でいくつのimg要素とかがあるのかわかんないんだから、そんなのでイイ感じに取られる曖昧な挙動は逆に困る
要素をid指定で取ったあと.ChildNodesで自分で辿ったりする必要がある
querySelectorが使えれば楽なんだけどね
何度も似たような質問を繰り返すよりもまずHTML DOMの基礎を多少でも勉強しないとずっとハマるだけだし応用もできないよ ありがとうございます。HTML DOMを勉強してみます。 PowerShellである処理について、変数の値だけ変えてそれぞれに同じ処理を実行したい場合、以下のように変数の値の数だけ実処理を複数段書けば実行できました。
ただ、これだとスマートではないと思いますので、ループ処理?のような形で最初に全変数を定義する等して、実際の処理自体は1か所だけにしたいのですが、どなたか書き方教えろください。。
------------
$変数a1 = 1-a
$変数b1 = 1-b
~~処理~~
------------
$変数a2 = 2-a
$変数b2 = 2-b
~~処理~~
------------
$変数a3 = 3-a
$変数b3 = 3-b
~~処理~~
------------ こんな初歩の初心者にpowershellの配列は難しい気がする
別の規格がちゃんとしてる言語を1つでも履修して出直してもらいたいな
プロの俺でもフィルタ関連とか関数から返した場合とかでしょっちゅう間違えるんで… ベテランでも諳んじて一発正解するのは難しいかったりするけど、シェルなんだから試行錯誤で構造化プログラミングの感覚を摑めばいいと思うよ
固定長配列でハコとして使う分には落とし穴もそうないのでは
パイプは使うかもしれないし使わないかもしれない
せっかくの気付きなんだから試してみるチャンス まずforeach文で作ってみればいい、そんな難しくはない
foreach-objectとかのコマンドレットにしたい、てのは次の段階にしてみよう .NETのジェネリックなコレクションを使う癖を付ければpsの変な仕様に振り回されないで済むかも そもそも配列やコレクションをループで回したりするのはPowerShell的な発想ではない
積極的にパイプを使うんだよ
それに馴染めないならもうインラインでC#書いたほうがいい 初学者がパイプの意味を理解するのはハードル高いと思う
コードが長くてもいいから自分のやりたいことをロジックにして組み立てる
それも出来ないうちからパイプでかくなんてさらに混乱するだけ
コマンドレットを見てすぐ処理を想像できるような慣れてる人ならいいと思うけどね >>320
ドトネトのコレクションはそのままパイプに突っ込めるでしょ
powershellのビルトイン配列(System.Array)をMS公開文書通りに使ってるとハマりやすいという話 初心者ですでにスクリプトも書いていてリファクタの相談なのに、パイプ使わないならC#でって…
原理主義なのか話を聞かない人なのか柔軟性が動脈硬化起こしてる人なのか ドトネトのコレクションはPS的には未知の参照型オブジェクトだから
PSのスコープの影響も受けないし、
配列みたいに勝手に構造を壊されたりもしないから積極的に使う事をお勧めしたい >>324
いや俺はpowershellのパイプは好きだぞ
反応頭悪すぎない? ID変わったけど323=328な
好きなものを無条件に全肯定しないと則敵認定ってまさに信者やん -pv/-ovで黒魔術できるのがpwshパイプの真骨頂、汚いけど…
パイプは一般にバッファ単位の目詰まりが難だけど、これは-obで自由に調節できる
-pv/-ov/-ovは共通パラメータだからいつでも使えるしpitfallsは大体これで解決できるからパイプ活用したいなら、最重要で覚えるべし >>330
パイプで最重要で覚える事はさあ、パイプはめっちゃコストコが掛かる書き方だな!って理解することじゃないかなあ
1行ずつ読んでパイプに渡してたら日が暮れるし…ずっとパイプの中で暮らさないといけない程変な言語でもない…
あっこの処理、パイプで連携したら効率いいかも…なんてあんまないのでな
これがパイプの真骨頂!って例を見せてくれたら、まあ考えを改めてもいいが…君の発言は新しいもの好きの勇み足発言にしか見えなくて痛々しい… PowetShell大好きパイプ大好き
可能な限りパイプを使うように努めてるよ アホらし
C#と同じように書きたいならAdd-TypeでC#書けばいいでしょ 結局どんな言語や書き方であろうと慣れでしか無い
読み辛いとか言う奴の大半が適応力やワーキングメモリの低い低能 2つ以上のcsvをできる限り簡単に結合する方法ありますでしょうか。
a.csv
id,name,gender
以下データ
b.csv
address,phone
以下データ
$firstcsv = a.csv
$secondcsv. = b.csv
$ketugou = connect-csv -delimiter ',' firstcsv[0] + firstcsv[1] + $secondcsv[0] + $secondcsv[1] + firstcsv[2]
$ketugou
id,name,address,phone,gender
以下データ
という感じであれば最高です。 bash -c "paste -d , a.csv b.csv" カラムの順序指定もしたいみたいだから、cutとかでもう1処理いるね。
PowerShellだと
(>>338) | ConvertFrom-Csv | select id,name,address,phone,gender | ConvertTo-Csv
ただしConvertFrom-Csv・ConvertTo-Csvは
元データを正確に再現する必要がある場合には難あり。
(Trim()が掛かるとかダブルクォーテーションで括られるとか。) paste使えない環境とか、Trim()掛かると困るとか、PowerShellだけで実装したい場合
function Merge-Csv {
Param (
[Object[]] $InputObject,
[string[]] $Header,
[char] $Delimiter = ','
)
$tbl = [Data.DataTable]::new()
# 1行目をカラム名として使用
foreach ($csv in $InputObject) {
$tbl.Columns.AddRange(($csv[0].Split($Delimiter)))
}
# 各CSVの同じ行同士をDataRowにする。
for ($lineIdx = 0; $lineIdx -lt $InputObject[0].Length; $lineIdx++) {
$rowData = @(
foreach ($csv in $InputObject) {
$csv[$lineIdx].Split($Delimiter)
}
)
$null= $tbl.Rows.Add($rowData)
}
# カラム順序を指定順序に変更する。
for ($order = 0; $order -lt $Header.Length; $order++) {
$tbl.Columns[$Header[$order]].SetOrdinal($order)
}
# CSV形式で出力
foreach ($row in $tbl.Rows) {
$row.ItemArray -join $Delimiter
}
} 注意:
・CSVは1行1要素の配列で、1行目にヘッダがあり、データに区切り文字を含んでいない想定。
・各CSVのヘッダに重複はない想定。
・1つ目のCSVの行数を基準にしている。
・エラーチェックしてないので適宜追加すること。
例:
$csv1 = @(
@"
id,name,gender
csv1.r1.id,csv1.r1.name,csv1.r1.genger
csv1.r2.id,csv1.r2.name,csv1.r2.genger
csv1.r3.id,csv1.r3.name,csv1.r3.genger
"@ -split '\r?\n'
)
$csv2 = @(
@"
address,phone
csv2.r1.address,csv2.r1.phone
csv2.r2.address,csv2.r2.phone
csv2.r3.address,csv2.r3.phone
"@ -split '\r?\n'
)
Merge-Csv $csv1, $csv2 -Header id, name, address, phone, gender | ConvertFrom-Csv | ft -a
id name address phone gender
-- ---- ------- ----- ------
csv1.r1.id csv1.r1.name csv2.r1.address csv2.r1.phone csv1.r1.genger
csv1.r2.id csv1.r2.name csv2.r2.address csv2.r2.phone csv1.r2.genger
csv1.r3.id csv1.r3.name csv2.r3.address csv2.r3.phone csv1.r3.genger >>338-340
ありがとうございます!
書き起こしてくれるなんて、感謝のしようがありません・・。
少し読み解くのに時間がかかりそうですが、半日考えても良い手が思いつかなかったので
しっかり読んで身に着けたいと思います。
ありがとうございました。 割とちゃんとした風なのが出てきてよかったな
>>337の結合は別にCSVとして処理する必要ねーじゃんと思ってたわ どこでみんな基礎を習得してるか気になる
都度ネット検索して見よう見まねでやってるけどちゃんと体型立てて学んだ方が良い気が最近してる
上のcsv解決の発想だって全然出てこないもの PowerShellから入る人なんていないでしょ
初学者がPowerShellでまともなプログラミングを学ぶのは難しいからC#でもやった方がいいよ 薄々そうじゃないかと思ってた
やっぱC#行くべきなのね >>345
C#もJavaも含めてほぼプログラム言語扱えない非プログラマーだけどPowershellは普通に学習出来たよ 会社では追加基本インストール禁止だから使える自動化ツールがVBA、WSH、CMD、Powershell くらいしか無いのです
VBA VBSは一通り使えるけどやっぱモダンなの使いたいって事でpowershellを使いこなしたいんですよ
っていうパターンは自分以外にもきっといるんだろうなって思って どの言語を学んでも解決ロジックなんかは数をこなして他人のソースサンプルを見るとかしていかないと見につかない
C#とか言語仕様は入門書が充実してるところが違うだけで読んだからといって
問題解決力が身につくわけではないことは心得ておかないとね
教科書を全部読んだからといって入試問題が解けるか?ってこと >>348
>会社では追加基本インストール禁止
そうさせましょう、そのために弊社の何とかを使いましょう、と営業してくるウザい連中がいるからね >>348
プライベートのPCでやればいい
プロでプログラミングやってる人間は学生時代やプライベートの時間など多かれ少なかれ仕事以外の時間を捧げてるんだよ
基礎から学ぶというのはそういう連中と同じ土俵に立つってことだ >>349
MS365関連の処理やらcmdスクリプトの代替やらログ処理やらを目的に応じてパイプ処理やら勉強してたらどうにかなった
元々プログラム言語としての習得したんじゃないから特殊かも 普通にpwsh使ってコマンドライン作業してれば覚える
スクリプトもその延長線上 いうほど精神論説いてるやついる?
〇〇論を聞いてるのに〇〇論を、そういう気の利いたフレーズを言ってみたい気持ちが先行してるように見える 本腰入れて文法とかほじくりたいならまずはpowershellexplainedってブログオススメ やりたいことが先にあって、それを如何に良く実現するかをあれやこれや試行錯誤していくのがいいよ
漠然と習得したいとか体系的にとかやってると漠然としか身につかない
あと人のものをよく見ること
こういうやり方があったのか、ってのを一つでも多く体験するのがいい コマンドラインで補完叩きながら必要そうなパラメータやメンバ探してれば大体望みのものが見つかるはず
フラッシュ暗記的にどこに使えそうなものがあったか思い出せればヘルプも引ける
俺がワンライナー以上の事をするときの具体的な手順
必要そうな関数を一つ定義してはパラメータ与えて何回かチェック、動けばfunction:から追記リダイレクトして最後にvimで手直ししてmainを添えて取り敢えず動くものを完成
暇なときに気が向いたら体裁整えたり関数まとめたり構造化
副産物として汎用性高そうなの出来たら$profileにも追記
こういうlisp的なサイクル回して使っていくのがいいと思う >>357
ありがとうございます
髭のオッサンは気になりますがチラ見した程度だと復習がてら良さそうです このコマンドがうまく動きません。
1行で書いて、うまく動かす方法を教えてください
powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process remove-item -ArgumentList C:\Users\Public\Desktop\test -Verb runas"
Start-Process : このコマンドは、次のエラーのため実行できません: 指定されたファイルが見つかりません。
とエラーが出て正常に実行できません。
powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process cmd -Verb runas"
powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process notepad -ArgumentList C:\Windows\System32\drivers\etc\hosts -Verb runas"
このコマンドはうまく動くので、同じ感じで行けるのかと思ったのですが、上のremove-itemコマンドの場合がうまくいきません。 remove-item.***なんて言う実行ファイルは存在しないから無理なのは当たり前
どうしてもstart-processに繋げないといけないの? >>362
レスありがとうございます。
> どうしてもstart-processに繋げないといけないの?
というわけではありません。
1行で管理者権限でRemove-Item C:\Users\Public\Desktop\testを実行する
ということが出来れば、どんな方法であっても構いません。
①powershell -NoProfile -ExecutionPolicy unrestricted -Command "Start-Process powershell -Verb runas"
②Powershellが管理者:Windows Powershellとして起動する。
③remove-item C:\Users\Public\Desktop\test を実行する
という①と③を1行でまとめる方法です。 >>363
自分もこの問題は解決出来なかった
UAC有効な環境で管理者権限使うならStart-processか管理者権限実行なのも一緒
しかしStart-processはコマンドレット実行出来ない模様
ワークアラウンドで別のcmdスクリプト作ってそいつをStart-processで実行させるという非スマートな力業でどうにかするしかなかった powershell -NoProfile -ExecutionPolicy unrestricted -command "Start-Process -Verb runas -FilePath powershell.exe -ArgumentList ‘-command remove-item C:\Users\Public\Desktop\test'"
試してないけどこんな感じで出来ん?
不備とかエスケープ処理が必要だったりとかあるかも
powershellから昇格させたpowershell呼んでそこでdel 定義した変数のメモリ開放は$nullの代入でいいのでしょうか?
メモリリソースが足りませんとエラーがでるので。 Remove-Variable
まあ設計を見直した方がいいと思うけど フォルダ内にあるすべての画像ファイルにおいて、その画像のWidthが1280のものだけを削除するスクリプトを作成中ですが、ファイルはどうやって削除するのでしょうか?
Get-ChildItem "D:\Download\test" | Sort Name | % {
$img = [System.Drawing.Image]::FromFile($_.fullname)
if ($img.Width -eq 1280) {
Remove-Item $_
}
}
だと
Remove-Item : Cannot find path 'D:\Download\test_01.jpg' because it does not exist.
とエラーがでるのですが、パスの設定方法がいまいちわかりません。 Remove-Item $_.FullName
か
$_ | Remove-Item
かな VSCode でも、コマンドプロンプト・PowerShell を使うと、
ファイル・フォルダ操作のアクセス権限が無いから、
右下のトーストに、そういうエラー通知が来る
そこで、アプリに対して、操作を許可する
それと、Windows でもファイルパス区切りに、/ を使える。
C:/Users/Owner/Documents/a.txt 今までこれをbatで起動させていました!
-------
sc stop DoSvc
@echo off
echo.
echo ====================
echo Enable_TaskScheduler
echo ====================
echo.
rem ----- win10_ServicePreparation_DoSvc -----
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DoSvc" /v "Start" /t REG_DWORD /d "4" /f
exit
-------
特定サービスの作動強制停止およびスタートアップ強制置換です
しかしこれでは管理者権限を付与する場合、人間がコンテキストで管理者実行をその都度選んでやらねばならず、
反映の有無も再起動が必要だったり再起動なしで切り替わったり不安定です
PowerShellのps1はそれら管理者権限付与の自動化や再起動不要が可能と聞きました
ネットにはバッチのような記述解説サイトが乏しいので、コードの代替案、またはおすすめの参考書等があれば教えてください〜 レジストリを直接編集するな
Windows 秘話: なぞのキー
https://docs.microsoft.com/ja-jp/previous-versions/technet-magazine/dn456530(v=msdn.10)
> 変更または操作されることがまったく意図されていない設定が存在します。そのような設定を見つけたときには、とにかくそっとしておいてください。 目的がテレメトリ関連の通信の遮断だしサービス削除しかないと思うけどな Stop-ServiceやSet-Serviceあたり使えばいいんじゃね ハード的家電において、メーカーの分解拒否声明は「簡単に直せる部分を民間でやられたら業績下がるやんけ」理論が殆どと、感電・火災防止が少しって感じ
同じくソフトにおいても、メーカーの調整拒否声明は「テレメトリを拒否されると情報転売が減って業績下がるやんけ」理論がほぼ全てで、僅かに不測の事態とその対応への危惧(面倒≒ユーザー側の心配はしていない)が含まれる感じ
大体、テレメトリの最終的な購入先は巡り巡ってそれらを利用したがっているガチ支那チョン露などの反社集団でしょうに
だから米国大手の支那癒着や制裁緩和の声が消えないわけで
例え吸われても、利用先が日本国内または米国のみであればそんなに問題視しませんわ
逆にDoSvcなんかは設定での表面上なOFFやグルポをしようと内部でMB単位のダウンロードをしっかりしていますし、
DoSvc動作用の基礎データか何かと期待したいものの時間経過で増大します→つまり120%ガチテレメトリなんですよ
そしてスタートアップを無効にしなければOS設定にかかわらず強制実行+勝手に通信+削除しようと復活増量し続ける
無効にしたスタートアップさえ手動(トリガー)へ勝手に戻される→高頻度自主改変がなければOSから「DoSvcの無い空間」を作り出せない
こんなソフトの癌とも言えるものを放置出来る方々の無神経さは平和の極みですな
安いからっつって支那産PCを大量購入し自衛隊へ配布した馬鹿で愚かな国賊官僚と同レベルに思う >>375 = >>382 でいいのかな
テレメトリを目の敵にするのは勝手だけど
だからってレジストリを直接編集していい事にはならないからね 会社の物とかでなければレジストリくらい好きに弄ったらいいだろ
それで何かあっても自己責任ってだけで レジストリ編集では期待通りにいかないことを体験的に踏まえた上で上手くいく手順としてPSでやりたいって流れの質問なのにレジストリ編集するな!ってクソバイスやん
自己責任を理解せずに杓子定規で正しさを主張し続ける人にはアレな傾向を感じざるを得ない batはレジストリの値を弄ってるのみにしか見えん
この後にPCを再起動でもさせるのか? だいぶ前から色んなところで聞いているけど
タスクマネージャーで権限がないから書き込めないとか
黒窓が出るのが嫌だとか
原因を追求する気もないのに聞いて回るクソヤロウだよ >>378
レジストリの変更はともかく
この記事の「おしゃれなレストランにいると考えてみてください」
という謎の例えはどうかと思うw >>386
弄ってるよ
その続き読んだ?
引き続きレジストリ弄りたがってるとしか読めないならアスペかもな バッチスレは論外ですな
batやスケジューラの挙動に関して最初から細かく説明していたのですが、どう考えてもガチ支那の五毛っぽいDQNが私の最後のレスを部分的にチラ見しただけで、答えている感じでしたね^^;
冷やかしがオナニーしている状態で、バッチスレの名が泣いていました
原因も提示し、それら打開策などの例や実施結果を挙げつつも、堂々巡りの、それもむっちゃ浅い既出内容をドヤ顔で書き込まれる感じ
バッチスレで唯一のプログラミングスレらしい収穫は「俺だったら.ps1で作る」という言葉、ただひとつのみでしたわorz
あとはなかなかまとまった時間が作れず、もう少ししたらps1版のサービス削除などもネット検索・吟味できそうです
最も盛んでしたwinXP時代にソフトを制作していた年代は今50前後?で開発・更新停止などが相次いでいますよね
そんで2022年現在、高校辺りでプログラミングを必修とする云々が出ている
間が20年くらいスッカラカンなのは日本の経済力低迷を表しているようで大変残念です
そりゃ今の官僚層が自衛隊へ支那産PC送ったりするはずですわ、そんなのが国を回しているんだから^^; 直接編集しちゃいけないなんてルールはないから好きにしな
無知が無学のまま弄った責任を負わされることを防ぐためのおまじないでしかないよ 行き着いた答えがレジストリ書き換えの定期実行だから頭悪いにも程がある 俺はちゃんとバッチスレにサービスの設定を変えるコマンドの事書いたぞ
コマンドのドキュメントのリンク付きで
このスレでも他の人が設定変更用のコマンドレットのこと書いてるし
何をどう見てるのやら レジストリなんて不整合があれば書き戻されることもあるのでレジストリ弄るだけで解決しない てかバッチスレが余りにも低水準かつ五毛全開だったからこそ呆れ、唯一のまともなアドバイスに従ってパワシェへ切り替えようとしているのにさ
わざわざ別スレのリンク貼ったりパワシェスレへ出張(笑)してきたり、ほんま意味不明ですわw
ま、ストーカー云々の類いはリアルもネットも気色悪いですしバッチスレ関係者から得られるものが無いのも経験済み
似た主題なので両方のスレを高頻度で訪問しているのかな、そう思うことにして特定のレスは流し聞きしときますよwww Linux なら、systemd とか
Windows の仕組みは知らないけど、
レジストリはその結果を収めたデータベースだから、
結果をいじっても問題解決にはならない
設定は各アプリ製作者が作っているものだから、
製作者以外の人間にできる事は、アプリをアンインストールする事だけ
設定にも様々な依存関係があるから、
アプリの内容も分からない人が、ある設定を変えても、どう作用するか分からない
例えば、アプリのメモリが解放されなくなって、
他のアプリも動かなくなるかも
それに設定を変えても、再起動しないと有効にならないかも知れないし、
再起動すると、設定が元に戻るかも知れない
OS 起動時の処理に、設定読み込みを登録しているかも知れない ウダウダと一体何の話をしてるんだ
いいからStop-ServiceとSet-Service使えよ
ただ老人がじゃれ合いたいだけなのか? >>375
管理者やSYSTEMじゃなくてTrustedInstallerとして実行しても駄目か?
もちろんレジストリをいじるんじゃんなくてSet-Serviceを使うんだぞ
もう見てないかもしれんが 最近foreach文のコレクションの要素を受け取る変数の名前をつけるのが
めんどくさくって
for文のカウンター変数の名前に i を使うのはよくありますが
foreachにも同じような定石ってありますか? 例えば$url = "https://yyyy.xxx/aaa/bbbb/2/"があり、最後の[2/]をカウンタを使ってアクセスしたいとおもいます。
その際、$nextUrl = ($url -replace ".{2}$") + $cnt + "`\"
で行けると思ったのですが、何か間違えていますでしょうか? arrayListの使い方がわからない。
----------------------------
$arrayReturn = new-object system.collections.arrayList
$col = new-object PSObject | select "A", "B", "C"
foreach ($i in 1..3) {
$col."A" = $i
$col."B" = $i + 1
$col."C" = $i + 2
$nul = $arrayReturn.add($col)
}
$arrayReturn
----------------------------
上記のコードを実行すると以下のようになってしまう。
A B C
- - -
3 4 5
3 4 5
3 4 5
本当は以下のようにしたい
A B C
- - -
1 2 3
2 3 4
3 4 5
なぜうまくいかないのか謎。 $col のnew-object生成をforeach{}内に移動してみては >>410
うまくいった
はあああああああああああああ!?
なんで!? なんでこれでうまくいくんだ!?
ループの中に入れたら毎回$colの中身が破壊されると思うんですけど???? PSObjectは参照型
ArrayListに追加されるのはオブジェクトそのものじゃなくてオブジェクトの参照だけ PSCustomObjectは積極的に使っていいものかどうか判断できない
結局C#でクラスや構造体宣言して使った方がいい気がするし
Powershellで作成したPSCustomObjectを、同ソースに埋め込んだC#コード側から参照する方法ってある? >>415
New-Object PSCustomObject や [PSCustomObject]@{} は
Win10 の v5.1 なら Add-Type の C# でなくとも class があるからスクリプトでの使用頻度は下がった。
Win7 の v2 では function NewABC {} みたいなコンストラクタ的な関数用意して積極的に使ってた。
Win10 の今でも ConvertTo-Csv へ渡す前に日時や数値を書式指定して文字列化するために使ってる。
CSV に日本語カラム名が欲しい時に日本語プロパティ名の class 用意するのはなんか気が引けるけど
[PSCustomObject]@{} や Select-Object での誰が見ても短命なオブジェクトなら気にならない。
データだけでメソッドがなく複数作るなら System.Data.DataTable も有り。
.Columns.AddRange([string[]]) でプロパティ(DataColumn)定義して
.Rows.Add([Object[]]) でデータ(DataRow)追加する使い方なら意外と手軽に使える。
日本語カラム名の使用も問題ないし。 -replaceと-ireplaceの違いって分かりますか?
まだ勉強中ですが、当然のように出てきて両方同じ説明しかされてないので気になって調べてみてもどこにも解説がなくて…
扱える値の範囲が違ったりとかするんでしょうか?
普通はどっちを使うものなんですか? 1.完全に理解した←初心者
2.チョットワカル←中級者
3.全然判らん←上級者 >>418
https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.2
既定では、 -replace 演算子では大文字と小文字が区別されません。
大文字と小文字を区別するには、次を使用します -creplace。
明示的に大文字と小文字を区別しないようにするには、次を使用します -ireplace。
replaceの既定動作を変更する方法は知りません。
大文字小文字を区別しようがしまいがどっちでもいいときは replace
そこんとこ間違ってもらっちゃ困るときは ireplace か creplace
普通がどっちかは分かりません。 例えば、Ruby のCSV 処理なら、
require 'csv'
input_csv = <<"CSV_TEXT"
id,果物
1,りんご
21,スイカ
33,みかん
CSV_TEXT
# 2次元配列
ary = CSV.parse( input_csv, headers: true ).each do |row|
row[ '果物' ] = "レモン" if row[ 'id' ].to_i == 21
end
p ary.to_a
#=> [ ["id", "果物"], ["1", "りんご"], ["21", "レモン"], ["33", "みかん"] ] >>420
ありがとうございます!
理解できました!
明示的に大文字の区別をつけるかつけないか指定する際に利用するものなんですね!
たしかにそれだと【普通】は場合によるとしか言えないですよね パワシェルの-replaceは勝手に右辺を正規表現と解釈するから
それが必要ない場合は文字列.Replace()のがいいよ >>423
そうですね!
>>424
おお、知りませんでした。
ありがとうございます! Windowsでコマンドラインシェルとして使う場合に
外部コマンド引数のクオーテーションの振る舞いをなんとかして欲しい
例えばpwshを外部コマンドとして使うとして
pwsh -nop -c "`$a = 'abc'; `$a | out-host"
は期待通り abc が出力されるのに
pwsh -nop -c '$a = "abc"; $a | out-host'
はエラーになるの不便過ぎる 補完が有効になってやっとまともに使えるようになったなよくこんなクソ長くて覚え辛くて入力し辛いコマンドレットなんて使ってるよなお前ら
しかしMSって言語やフレームワークでもそうだが命名規則にセンスねーゎ
なんでnpmやgitみたいに使いやすく作れないのか壊滅的にセンスねーゎ PS> pwsh -nop -c "`$a = 'abc'; `$a | out-host"
abc
PS> pwsh -nop -c '$a = "abc"; $a | out-host'
abc: The term 'abc' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
これほんと何がどうしてこうなるの? pwsh.exeへのコマンドラインとして解釈されるから、まずOSのルールに従って引数リストが次のように分解される
-nop
-c
'$a
=
abc
;
$a
|
out-host'
pwsh.exeの内側でコマンド文字列を再結合した時点では既にダブルクォートが失われているという寸法 無茶言うなよ…
pwshの-cより右ならスクリプト扱いで、cmdやその他大勢の右ならOS解釈? pwshという同名のオレオレアプリの類だったときもスクリプト扱い?
言語仕様の一貫性的にあかんことになるだろ常考 >>429
「'$a = "abc"; $a | out-host'」の「'〜'」は
そのコマンドライン上の文字列リテラルである事をPowerShellに指示してる事になって
PowerShellは1つの文字列「$a = "abc"; $a | out-host」の事だと受け取る。
コマンドが実行ファイルの実行で、その引数の文字列にスペースがあると
その文字列全体が「"〜"」で括られて文字列「"$a = "abc"; $a | out-host"」になる。
↑Windows PowerShell v5.1のTrace-Commandで確認
↓自信なし
powershell実行時の引数パース時に「\"」とか「"""」とかではない
単独「"」は不正な(余分な)メタキャラとして取り除かれるもよう。
で-cには「$a = abc; $a | out-host」が渡る。
>>430
確か「OSのルール」だと、実行ファイルに渡される引数は単一の文字列で、
スペースで区切ったり「"」を特別扱いするのはpowershell(pwsh).exeの独自のただし非常に一般的な仕様。
(大抵は、exeにコンパイルした際のコンパイラの仕様。) Linuxのpowershellなら
PS> pwsh -nop -c '$a = "abc"; $a | out-host'
abc
になるんだろうな コマンドプロンプトで
pwsh -nop -c "$a=\"abc\"; $a | out-host"
とするのは " 内部の " をエスケープするように見えて自然に納得できる
Windows版のPowerShellだけ
pwsh -nop -c '$a=\"abc\"; $a | out-host'
とするのは ' 内部の " をエスケープさせられて気持ち悪すぎる
おまけにLinux版でこう書くと動かないんでしょ >>436
コマンドプロンプト(cmd)だともっと高難易度の問題がある。
cmdのメタキャラ(&, |, <, >など)が偶数番目の「"」の後にあるとだめとか、
powershellコンソール以上に問題有り。
pwsh -nop -c "$a=\"&abc\"; $a | out-host"
同一のシェル名(pwsh)であっても、OSによって他プロセス起動の作法が違うのは仕方ないと思う。
国や地域で言葉や文化が違っても仕方ない感じ。
(POSIXとかに規定あればば別だが。)
例えば「ping」を動かすだけにしても結局オプションも挙動も違う訳だし、
現時点では他プロセス使う時点で、移植性考慮はプログラマの領分かな〜と思ってる。 PowerShellのコンソールやスクリプト上で他プロセスを起動したい場合、
自分だとほぼ下記2通り。
(A) System.Diagnostics.ProcessStartInfoを使う。
(ちゃんと制御したい場合。スクリプトだと基本これ。)
$si = [Diagnostics.ProcessStartInfo]::new()
$si.FileName = 'powershell.exe'
$si.Arguments = '-nop -c "$a = \"abc\"; $a | out-host"'
$si.UseShellExecute = $false
$proc = [Diagnostics.Process]::Start($si)
$proc.WaitForExit()
(B) 引数を1つずつ@()に入れ、「"〜"」としたい場合は最初から値に含める。
(コマンドラインとかで手軽に。…手軽?)
& 'powershell' @('-nop', '-c', '"$a = \"abc\"; $a | out-host"') MSYS2のbashもWindows上のコマンドラインシェルだけど
pwsh -nop -c "\$a = 'abc'; \$a | out-host"
pwsh -nop -c '$a = "abc"; $a | out-host'
のどちらでも動くんだよね
PowerShellには頑張って欲しい わざわざProcessStartInfo使うとかめんどくさいわ
Start-Processでいい
Start-Process -FilePath 'powershell.exe' -ArgumentList '-nop -c "$a = \"abc\"; $a | out-host"' -NoNewWindow -Wait ProcessStartInfoが面倒なのは同意。
Start-Processで済む時は使う事もあって
大体はUseShellExecute = $trueの時かな。
Start-Processを使わない一番の理由は-Redirect*がファイルパス指定な事。
出力を無加工でファイル出力したい事がまずないので使いづらい。
なんで-PassThruのProcessオブジェクトの出力制御変更のスイッチじゃないのか。
標準出力・エラーを同時に制御するとデッドロックしやすいからかな。
Start-Processがその辺うまい事制御してくれたらスクリプトでも使うんだけど。 コマンドラインパラメーターの処理はexeをビルドした処理系のスタートアップコードに依存するのだ
MSのC/C++やMingwとかで微妙に変わってくるのだガハハ
WindowsでC/C++/C#の場合argvとかではなくWin32APIのGetCommandLineで取得するのが一番正解に近い "" や \" が必要な仕様は気持ち悪いって話をしてたつもりが…
ネイティブコマンドを呼ぶのはコマンドと引数を並べて書くだけが普通でしょ
about_Parsing の icacls を呼ぶ例もそのまま並べてる
そのままと異なる動きをさせたい時以外は、>>438 も>>440 も面倒すぎる 引数のワイルドカードを展開するかしないかみたいなやつね MSもこの辺の気持ち悪さ・分かりづらさは分かってるみたいで
core v7とかだと環境変数かなんかで、パースルール変更できるんじゃなかったっけ。
Win10のv5.1しか使わないから知らんけど。 >>443
> ネイティブコマンドを呼ぶのはコマンドと引数を並べて書くだけが普通でしょ
例えば
$a = "abc"; cmd /c "echo $a"
を実行したら「$a」と出力されて欲しくて
「abc」と出力されて欲しければ>>438,440ってこと?
好みが分かれるところかなー UNIXのシェルスクリプトのマネにならないようにした結果がこれ PowerShellは、記号に独自の意味を持たせているから、PowerShell職人を養成しないと使いこなせない。 PowerShell in ActionにはUNIXシェルを参考にしたっていろんな所に書いてあるけど
たとえば比較演算子とか powershellはPerlの匂いがする
俺が好きになった理由はここ >>450
記号に独自の意味を持たせてる言語は多数あるのでは。
というか程度の差こそあれ殆どでは。
学習せず「使いこなせる」言語はないでしょ。 powershellの記号が特殊とかはあまり思わないな
それより配列の扱いがトリッキーとかの方が職人の養成が必要と思う ファイル名に[]が含まれてて苦労した人なのかなと思った >>453
バッチファイルとの相性が最悪なのに気づかないとは情けないよ、あんた。 >>451
あらゆる言語を参考にして、いろいろ混ぜ込んで、奇妙奇天烈なものになってしまった。 まあ最大の問題は、空白をトークンの区切り、改行を入力に終わりとしたことだな 変数のスコープが他と違うPowershellには何も期待してない
グローバル変数を更新したつもりがローカル変数と見なされたりして使い難すぎる
グローバルデータを全部.NETのコンテナに逃がしてようやく使えるようになった 超ヘンテコなJavaScriptだって一世を風靡したんだからPowershellだっていけるし(震え声 >>461
あんたPowerShellをほどんど知らないでしょ? >>456
そんな話してなかったでしょ。会話になってないよ。
バッチ(コマンドプロンプト)上でワンライナー書くときに
記号の取り扱いに注意しなくていいメジャー言語は一つも知らない。 >>463
個人的にはバッチは制限多過ぎだよね
今回の問題もPowershellというより旧cmm互換性のせいだし そもそもpsでスクリプト使うならバッチじゃなくてps1だろ >>460
どこがどうヘンテコって思い込んでるんだ? 久々にvbsで書いたらめっちゃ素直でスラスラ書けるわ
Powershellはせめてレキシカルスコープで作り直してくれ
クラス使えって? >>470
psだってレキシカルスコープだよ
どういう動作を求めてるのかはしらんけど PowerShellの悲しい点は、関数とスクリプトブロックが動的にスコープされることです。
しかし、私が驚いたもう1つの点は、変数が内部スコープ内でコピーオンライトとして動作することです。
$array=@("g")
function foo() {
$array += "h" Write-Host $array
}
& { $array +="s" Write-Host $array }
foo Write-Host $array
出力は次のとおりです。
g s
g h
g
これにより、動的スコープの苦痛が少し軽減されます。
しかし、どうすればコピーオンライトを回避できますか? これの解決策
([ref]$array).Value += "h"
ちとうんこすぎるね せめて問題を理解してからレスしろよ
この動的スコープとは何ですか?
ほとんどのプログラムは、理解しやすいため、レキシカルとも呼ばれる静的スコープを使用します。ソースコードを見ると、範囲内にあるものがわかります。Pythonの例では、スコープ内のxの唯一の値はxのグローバル値です。
対照的に、PowerShellは動的スコープを使用します。このモデルでは、スコープスタックに基づいて実行時に変数を検索します。関数を呼び出すたびに、新しいスコープを作成し、すべての値を親スコープからそのスコープにコピーします。PowerShellの例では、printXがsetAndprintXから呼び出されると、setAndprintXスコープで設定された$xの値を取得します。
なぜ動的スコープが必要なのですか?
字句スコープよりも動的スコープを選択する理由について、適切な説明を思い付くことができません。
「健康は病人だけが見ることができる王冠です」 function foo() {
$global:array += "h" Write-Host $array
}
& { $global:array +="s" Write-Host $array }
ってやるだけじゃねーの?
そもそもグローバル変数自体はそれ程使わん、ましてや関数やスクリプトブロックで更新なんてほぼやらん >>477
PowerShell in ActionによるとダイナミックスコープはUNIXシェルを参考にしたらしい using namespace System.Collections.Generic
$list = [List[string]] @('ggg');
'$list={0}' -f ($list -join ', ') | oh
function f {$list.Add('fff'); 'f={0}' -f ($list -join ', ') | oh;}
&{$list.Add('sb'); 'sb={0}' -f ($list -join ', ')|oh;}
f
'$list={0}' -f ($list -join ', ') | oh
↓
$list=ggg
sb=ggg, sb
f=ggg, sb, fff
$list=ggg, sb, fff >>480
.NEtのListコンテナ使うと意図通り動くのはなんでなん
Powershellの配列の変数は値型とか?
この辺をちゃんと理解ておきたい Listかどうかは関係ない 変数に新しい値を代入してるかどうか
>>474の $array += "h"は 新しく作った配列を $array に代入してるけど
>>480の $list はそんな事してないでしょ >>482
えーつまり$array += "h"は文字列への追加じゃなくて
やってることは$array = $array + "h"相当で新規に文字列のインスタンスとローカル変数が作成されるってことなの?
$arrayに対してのAdd相当は$global:的な装飾子以外にないの? メインclerだけど、動的静的スコープの使い分けがclの武器と刷り込まれてた
評判悪いのか…
呼び出し側から振り分けられるのは便利では?出力先とか lispのようにメモリ上フラットにオブジェクトが住む思想(~pwshのfunction:プロバイダ)だと、動的スコープになるのが自然では
レキシカルな文脈が無いのだから Powershellの配列は固定長だよ
追加はできない
+=演算子はその見た目のイメージ通り、新しい配列による再代入を伴う
これはスコープとは関係ない問題 ミュータブルかイミュータブルか、あと参照の話がごっちゃになってるよね
GetNewClosureはclのfunctionフォームと等価だね >>479
unixシェルもpwshもclもそうだけど、関数定義をズラズラっとダンプできて、それをちゃんと読み戻せる言語は原理的にレキシカルスコープでは有り得ない
(暗黙のうちにletやクロージャ生成を行う)ブロックぽい構文でレキシカルスコープを模倣することは可能だけど LISP族はletか何かで変数に対しての宣言を必ずするからダイナミックでも違和感ないでしょ
Powershellの違和感は暗黙的に変数の意味が代わるところじゃないかな コード適当に書いていってある程度の規模になった頃にそろそそ関数化でもすっか!
ってなった時に下手にグローバル変数更新してたりすると即はまるなコレ
しかも一見何が悪いのかさっぱり判らないという
Powershellコーティング十か条でも壁に貼っとかないとな いや下手にグローバル変数更新はできんだろ、参照だけ >>490
10ヶ条の最初に
・グローバル変数は使うな、ましてや更新する奴は死刑
って書いとけ >>491
MSの自動翻訳は的が外れてて知りたいことは何も書かれてない…
個人のurlの人は説明が無茶苦茶で到底理解できてると思えない中身。スコープでググってこれが引っかかるなら悪質
結局のところ、参照渡しや参照書き換えの仕方を知ってればスコープはほぼ気にしなくていいという結論に至った
値渡しだけで済む書き方ができればなお良い スコープの話をしたいわけじゃなかったのなら最初からそう言ってほしかった Pesterって使ってる?
使ってないとしたらUTどうしてる?
証跡としてコードカバレッジ出す目的に今も使ってるけどPowerShellの言語としてとか実行ホスト(exe)の機能ではなく
式単位にブレークポイント仕掛けて実現してるんだかで処理速度も普段よりかなり遅いし、あんまり便利って気がしない。
(うろ覚え)記述によってはうまくコードカバレッジに反映されない事もあった気がする。
そんとき忙しくて詳しく調査してらんなくてコードの方変えた気がする。
確かif文の条件内で変数に代入したりしてる場合だったかな。
while($null -ne ($line = $stream.ReadLine())){}みたいなのだったかな。 PowerShellなんか想定した運用で動きゃいいでしょ
真面目にテスト書くようなものはC#で書きなさい 以下のごく普通?のjsonがConvertFrom-Jsonだと意味不明なエラーで通らなかった
'{"":"あーあ" }' | ConvertFrom-Json
エラー出力
ConvertFrom-Json : Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again.
At line:1 char:17
+ '{"":"あーあ" }' | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [ConvertFrom-Json], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.ConvertFromJsonCommand >>500
PowerShell Core ではバグとして修正されてるらしい
https://github.com/PowerShell/PowerShell/issues/1755
PowerShell Core は使ったことないが、Windows PowerShellが認めるJSONは独特なので外部とのデータ連携に使うには向いてない印象。
PowerShellからPowerShellへの受け渡しなら苦労は少ないけど、それならJSONで入出力する必要がないことが多い。 名前なしの値ってjson採用してるアプリで普通に使われるんだよね
困ったわい JavaScriptってプロパティ名で空文字列が使えるもんなあ
JavaScriptの仕様がファンキーすぎる気がしないでもない ハッシュテーブルの実装的には問題ないんだろうか?
どれとは言わんがある言語のハッシュテーブル実装用のハッシュ関数(種はランダム)に空文字列""通したら恒等的に0なんだが バッチスレでPowerShell使いなよってアドバイスもらって
GetでJSON取得⇒JSON要素出力がこんなに簡単に出来るなんて感動した
curlコマンドとjqコマンド駆使してやってたのがアホみたいだった
でも構文とコマンドレット覚えるのは面倒 種を要求するハッシュ関数ってよくあるんか?セキュリティ対策?
ずっと同じ値が帰ってくるならハッシュテーブル的には問題ないかと >>504 がなんか勘違いしてるんだろうと思う
種なんて聞いたことないし空文字列で 0 を返すのはよくある実装だと思う >>506
起動時環境ノイズから勝手に取ってくるのが普通かと
同じハッシュ値持つキーがあると、まあ実装によるがDoS攻撃のいい的
追加情報で判別にフォールバックしたり、テーブル作り直したり、非常に負荷がかかる
perl, python, pwshは少なくともそう
python -c print(hash(""))→0
python -c print(hash(" "))→ランダムなint64
pwsh -nop -c '"".GetHashCode()'→ランダムなint32
perlはスマホに入ってないのでまた
どちらも勝手に種植えてるね、Pythonは64bitにハッシュしてるから単純に強度が強いが、pwshが0でもランダムに見えるのに対し、常にf("")=0のpythonの実装はちょっと謎
fによって""と同じ値に写る文字列も毎回変わるので探すのも容易じゃないだろうけど、実際に規則性を見てしまうと他にも弱点ありそうな気がしてくる
事実としてpwshよりはwebで扱かれてるわけで、まあ大丈夫なんでしょう >>507
デバッグ用に手動で植える機能はあるはずだよ、マニュアルのどっか見たら書いてるはず、もちろん非推奨だけど 今perl環境無いので記述だけ、v5.8以来ハッシュ関数の種は秘密に植えてるようで、あと人力で植えたい人への植え方
誰か検証たのむ
https://perldoc.jp/docs/perl/5.36.0/perlsec.pod#Algorithmic32Complexity32Attacks
既にwebで流行ってた頃だと思うんだけど大丈夫だったのか 今perl環境無いので記述だけ、v5.8以来ハッシュ関数の種は秘密に植えてるようで、あと人力で植えたい人への植え方
誰か検証たのむ
https://perldoc.jp/docs/perl/5.36.0/perlsec.pod#Algorithmic32Complexity32Attacks
既にwebで流行ってた頃だと思うんだけど大丈夫だったのか 今perl環境無いので記述だけ、v5.8以来ハッシュ関数の種は秘密に植えてるようで、あと人力で植えたい人への植え方
誰か検証たのむ
tps://perldoc.jp/docs/perl/5.36.0/perlsec.pod#Algorithmic32Complexity32Attacks
既にwebで流行ってた頃だと思うんだけど大丈夫だったのか 今perl環境無いので記述だけ、v5.8以来ハッシュ関数の種は秘密に植えてるようで、あと人力で植えたい人への植え方
誰か検証たのむ
perldoc.jp/docs/perl/5.36.0/perlsec.pod#Algorithmic32Complexity32Attacks
(そのまま貼れない)
既にwebで流行ってた頃だと思うんだけど大丈夫だったのか で、件のjsの仕様だが、空文字でもよしなにハッシュしてくれるってことかいな?多分
空文字をキーとして使う事に関しては、言語固有のデータ型の概念も絡む
パスカル文字列でもc文字列でも、空文字列自体はいかなるバイト表現も持ち得ない
値がなけりゃ関数にも渡せない
文字数や終端の0埋めバイトごと渡せば値になるが、そこは思想の問題だろうね >>515
そこは言語リファレンスであって、リファレンス実装の(c)pythonとは(建前上)関係がない
インタプリタについてはこっち、hash関数のランダム化とどうしても植えたい人用
https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED ああすまん、最近の実装まで追いかけきれてなかったな
なるほど一つ賢くなったわ、ありがとう 実装のドキュメントもランダム化の有無に関わらず空文字列に0を返す事については触れてないな
まあ実装の詳細も詳細だし、保証する意味も無いから、気になるならソース読むしかない
気になるなら、この実装に問題無いんですか、と元気があるなら問い合わせる案件 とりあえずPythonでhash("")==0なことはundocumentedなので依存するコードは書いちゃダメってことかな
偶々タイプが面倒だったのか、それでもよく見つけたな
一点だけ分かって現実に問題になるかはともかく、理想的なハッシュ関数の振る舞い(=完全にランダムに見える)として好ましくないのは確か
pwshのこういう面白ネタないかな、まあまだまだ開発中なので山ほどありそうなのがアレだけど 面白そうなのでハッシュ衝突させてみた
d=dict()
d[0]="int 0"
d[""]="nullstr"
print(hash(0), hash(""), d)
0 0 {0: 'int 0', '': 'nullstr'}
たった2個ぶつけて死ぬ事はまあ無いが、いくらか試して中身は予想付いてきた
スレチごめん 面白そうなのでpwshでも
$h=@{0='int0'; ''='strnull'}
write (0).GetHashCode(), ''.GetHashCode(). $h[0, '']
→0 498565465 int0 strnull
cpythonと違い空文字列は0とは別物のようです
なおpython/pwshともに値の等しいintとfloat型をキーにしようとしたらエラー
([double][int]::MaxValue -eq [int]::MaxValue)
→True
キーにfloatを使うアホが居るかは不明だけど、[double]の範囲では全ての[int32]が表せるので今の実装の整合性に問題はない
さらに型を大きくするとfloatで表せる整数は歯抜けになってくるけどまあ
-0.0→-0.0
(-0.0).GetHashCode()→0
整数としての値ですね
$nan=[double]::NaN
$nancode=$nan.GetHashCode()
-214643572
$maxcode=[double]::MaxValue.GetHashCode()
214635072
$nancode + $maxcode→0ですね
ところでナンだか見慣れた数字が…
2gb, 4gb→2147483648 42949672
$nan -eq $nan→False
そう決めたからまあ、そうなんだけど
$nancode -eq $nancode→True
なんだかなー 複数のNaNをキーにしたハッシュリテラル書くとInvalidOperation例外投げるな、Duplicate Keys 'NaN' are not allowed...らしい
アサインすると値が上書き
見方によってはハッシュテーブルというアルゴリズムの敗北と言えるかもしれん
困る機会も思いつかないのが幸い どのNaNとNaNも互いに値が等しくないからといって、キーがNaNまみれのハッシュ$nansが作れたとして
じゃあ$nans[NaN]はどの値を返せば正解なんだよ 抽象データ構造としての連想配列なら、NaNがインデックスとして渡されたら探索すらせずに常に$nullを返せばいい
NaNと-eqなキーは$nansがNaNまみれであるかに関わらず存在し得ないんだから
ハッシュテーブルはあくまで"ほぼ-eq"を使った連想配列の実装
$nan=[double]::NaN;
$ht=@{$nan="abc"}; $h[$nan]
は"abc" を返すはず そもそもnanは論理学と数学基礎論の公理、同一律を否定しているので、論理的思考を行っている限り無矛盾に理解することは原理的に不可能だぞ
考えるな、感じろ >>505
jqはフィルターとして便利なだけじゃなく、プログラミング言語として非常に面白いと思ってるので、学ぶ価値ありだと思うよ
移行前はcmd+vimで何でもやってたな
vimは安定してwinサポートしてたし、ユニコ以前から常に日本語パッチ供給されてて、強力なテキスト処理とある程度の構造化データ処理もできる入手性よいツールとして稀有だったはず
引数に直接スクリプト渡して非インタラクティブにバッチ処理できるからbatの中身はほぼvim/exスクリプトだった
多分2000年あたりでvim並みの機能かつ日本語サポートもしっかりしてるのはperlくらい コードエディタとしては愛用してるけど、vimをコマンドとして使う発想に時代を感じる こんな感じかね
vim -es "g/\W?\|\Wwhere/ s//Where-Object/p" -c wq $profile
こわいから-c wqはしないけど
findstrでパターンマッチ、for /f ... in (file.txt)で行毎にスキャンして置換したのをechoとかやってたな for /f "tokens=...delims=...skip=...eol=..."はプレーンな行毎のテーブルの処理には悪くない、明示的にフォーマットを指定してパースするので、むしろ分かりやすいまである
クオートやエスケープの解釈、ダメ文字などイレギュラーに全く対応出来なかったり、/フラグ毎にforの挙動が別コマンドと言えるほど違ったりで、融通が全く効かないのがアレというだけ
for /fで扱いやすいフォーマットで書いて読む閉じた世界に住んでるなら幸せ >>530
あーよく見たら$proflleか
フリーフォーマットをfor /fで走査は黒魔術になるな、行をどう分割するにしろ、変数展開時の文字列置換は分割単位毎だし、行内複数マッチの場合どうするのか考えるだけでぞっとする
vimに引数でコマンド渡すにはたとえ単一引数でも-cが必要、兄弟のsedやvi(m)のエイリアスexは専ら引数にコマンドを期待するので-e落として紛れはないけど、vi(m)はその名の通りvisualエディタだからはじめの引数にファイルを期待する 最近仕事で触ることになって使い方習ったけど全然わからん 右も左も分からないなら、とりあえず良く使いそうなコマンドレットはエイリアスが事前に定義されてるので、galで出てくるのを順番に弄り回したりghするといいかも 基本文法を覚える前にVB.NETでモジュールメソッド作成して呼び出すやり方覚えたら動けばいいやでそっちばかり使ってしまってなかなか覚えられない $OutputEncoding の初期値をUS-ASCIIからShift-JIS 932に変更したいのですが方法が分かりません
変更は
$OutputEncoding = [Console]::OutputEncoding
$OutputEncoding = [System.Text.Encoding]::GetEncoding(‘Shift_JIS’)
などで出来るようなのですが既定値を変えたいです
やりたい事はcmd上でripgrepをパイプで繋いだ際に文字化けしないようにしたいのですが
https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#pipe-non-ascii-windows
$OutputEncoding の既定値を変えられたとしてもcmd上でも効果があるのかは試してみないと分かりません
こちらの解決法が分かる方が居ましたら是非教えて欲しいです プロファイルに記述、じゃだめ?
PS> notepad $PROFILE.CurrentUserAllHosts >>537
ありがとうございます
$profileでやってみました。UTF-8でなら使えそうなのですが
$OutputEncoding をsjisにしたps上でもrgがUTF-8で吐いてるので無理みたいです
【.cmd】 バッチファイルスクリプト %13 【.bat】
https://mevius.5ch.net/test/read.cgi/tech/1542779527/496
参照先のようにUTF-8にすれば一応化けずに使えるのですがUTF-8だとコマンド類がascii以外機能しないものが多いのでバッチなどでは使いづらい
sjisで使えたら貧弱なfindstrに置き換えられ便利になると思ったのですが残念です findstr置き換え目的でPowerShell持ち出すなら、Select-Stringとかの手もある。
rgの高速検索のメリットがPowerShellのオーバーヘッドを上回るなら、
例えば以下のような処理を関数なりスクリプトなりにしておくといいと思う。
スクリプト化しておけばcmdからもpowershell経由で使える。
#…けど、他のgrepコマンド導入した方が良さそうな気がする。
$path = "検索対象ファイルパス"
$pattern = "検索パターン"
$si = [Diagnostics.ProcessStartInfo]::new("rg.exe")
$si.Arguments = '"{0}" "{1}"' -f $pattern, $path
$si.UseShellExecute = $false
$si.RedirectStandardOutput = $true
$si.StandardOutputEncoding = [Text.Encoding]::UTF8
$proc = [Process]::Start($si)
$stdout = $proc.StandardOutput
while (! $stdout.EndOfStream) {
$stdout.ReadLine()
} 誤:$proc = [Process]::Start($si)
正:$proc = [Diagnostics.Process]::Start($si)
動作確認してないので他にもあるかも。 同階層にフォルダツリーA~Zまであり、それぞれのツリーの中身はバラバラです。
それぞれのツリーのCSVを出力したいのですが、やり方がイマイチ分かりません。
CSVにはツリー名、ツリー毎の合計サイズと、ツリー毎に最新更新ファイル(ファイル1つだけ)の日時を抜き出したいです。
PSFolderSizeをインストールして色んなサイトから拝借してコピペの集合体でやってみたのですが、各ツリー内の更新日を取得する部分とフォルダサイズを取得する部分を同時に行う事が私の頭では無理でした。何方かお助け頂けないでしょうか ツリーて何だ?
フォルダに階層があってその中全部見たいということならGet-ChildItem -Recurseだぞ ・コード貼ってバカにされるの嫌
・具体例挙げるなど仕様詳細説明面倒臭いから文章から汲み取れ
・全部やれ
こういうことだろう
舐め腐ってるヤツはスルーしときなよ 本人はいたって真面目なパターンだろ
ググった情報を組み合わせるスキルがないということは、悲しいかな往々にして他人に要件を一発で伝えるスキルも不足しがち
同時にやるのが無理めに感じるのはパイプを使おうとしてるからだろう
for文とローカル変数で書き変えれば簡単 伝えるスキルうんぬんの前に
> PSFolderSizeをインストールして色んなサイトから拝借してコピペの集合体でやってみたのですが
って言うならそのコード上げろって話
ヘタに説明するより100倍早い いやできなかったコード上げても何の説明にもならんから
現状と得たい結果の図示だな コードを上げたほうがいいんじゃないかとか図で伝えるべきなんじゃないかとかそういうの引っくるめての伝えるスキルだよ
コミュニケーションは言葉に限定されない >CSVにはツリー名、ツリー毎の合計サイズと、ツリー毎に最新更新ファイル(ファイル1つだけ)の日時を抜き出したい
変なモジュール入れんでも数行で書けるからがんばれ しっかしコマンドレットがコマンドライン実行時とスクリプト内呼び出しでパラメータ解釈が異なるって
どんなキチガイが仕様考えたのか気になるわw
switch型パラメータをスクリプト内で動的に外したり与える方法がないとか終わってる >>550
何を言ってるんだ?
ちゃんと質問したらお前の間違いを教えてもらえるかもしれんぞ Ruby で、win32ole を使って、
フォルダ以下のサイズ(再帰的な子孫も含めて)は、
require 'win32ole'
fso = WIN32OLE.new( 'Scripting.FileSystemObject' )
folders = [ "C:/Users/Owner/Documents/test_1",
"C:/Users/Owner/Documents/test_2" ]
folders.each do |folder|
folder_obj = fso.GetFolder( folder )
puts File.expand_path( folder_obj.path ) # \ を、/ に変換する
puts "#{ folder_obj.name } : #{ folder_obj.size }"
end
出力
C:/Users/Owner/Documents/test_1
test_1 : 28803
C:/Users/Owner/Documents/test_2
test_2 : 4390 Ruby で、フォルダ以下のファイル(再帰的な子孫も含めて)で、
更新時刻が最も最近のものを求めた
folders = [ "C:/Users/Owner/Documents/test_1",
"C:/Users/Owner/Documents/test_2" ]
folders.each do |folder|
# 絶対パスのディレクトリ名の後ろに、* を付けること!
# . で始まる、隠し directory, file を除く
glob_pattern = folder + "/**/*"
latest_file = Dir.glob( glob_pattern )
.select { |full_path| File.file?( full_path ) } # ファイルのみ
.max_by { |full_path| File.mtime( full_path ) } # 更新時刻が最も最近のファイルパス
puts "#{ latest_file }\n#{ File.mtime( latest_file ) }"
end
出力
C:/Users/Owner/Documents/test_1/a.txt
2022-05-19 14:38:35 +0900
C:/Users/Owner/Documents/test_2/x/x.txt
2022-02-24 16:01:54 +0900 Ruby で、CSV 形式で出力する部分は、
require 'csv'
result_ary = [
[ "C:/Users/Owner/Documents/test_1", "28,803", "2022-05-19 14:38:35 +0900" ],
[ "C:/Users/Owner/Documents/test_2", "4,390", "2022-02-24 16:01:54 +0900" ]
]
# 2次元配列を、CSV 文字列に変換する
csv_str = result_ary.map( &:to_csv ).join
print csv_str
出力
C:/Users/Owner/Documents/test_1,"28,803",2022-05-19 14:38:35 +0900
C:/Users/Owner/Documents/test_2,"4,390",2022-02-24 16:01:54 +0900 >>541
@(
"C:\dir1"
"C:\dir2"
) | %{
$prop = [Ordered] @{Path=$_}
$file = @(Get-ChildItem -LiteralPath $_ -Force -Recurse -File)
([Ordered] @{LastWriteTime='Maximum'; Length='Sum';}).GetEnumerator() | %{
$opt = @{'Property'=$_.Key; $_.Value=$true;}
$prop += @{$_.Key = $file | measure @opt | select -exp $_.Value}
}
[PSCustomObject] $prop
} | ConvertTo-Csv -NoTypeInformation >>555
おおー無駄がなくてすごい
これぐらい書けるようになりてぇ
開始は配列の変わりにコマンドレットでも良さそう
Get-ChildItem -LiteralPath <親フォルダ> -Directory | ... >>556
確かに。てか半端に汎用性意識せず、素直にこんなんでも良かったな。
@(Get-ChildItem -LiteralPath <親フォルダ> -Directory).FullName | %{
$file = @(Get-ChildItem -LiteralPath $_ -Force -Recurse -File)
[PSCustomObject] @{
Path = $_
LastWriteTime = ($file | measure LastWriteTime -Maximum).Maximum
Length = ($file | measure Length -Sum).Sum
}
} | ConvertTo-Csv -NoTypeInformation いや、こうか。
Get-ChildItem -LiteralPath <親フォルダ> -Directory | %{
$file = @($_ | Get-ChildItem -Force -Recurse -File)
[PSCustomObject] @{
Path = $_.FullName
LastWriteTime = ($file | measure LastWriteTime -Maximum).Maximum
Length = ($file | measure Length -Sum).Sum
}
} | ConvertTo-Csv -NoTypeInformation 試してないけどフォルダにファイルが1個も無い場合を考慮できてない気がする 知らんかった。前者つもりだった。
(@() | measure -Sum).Sum → 0
(@() | measure Length -Sum).Sum → Null powershellはgciはともかくmeasureが遅くてファイルが多くなると辛くなるね
結局C#に丸投げとかの手段になりそう 試してないけど
Get-ChildItem -LiteralPath <親フォルダ> -Directory | %{
$Stat = $_ | Get-ChildItem -Force -Recurse -File | Measure-Object LastWriteTimeLastWriteTime, Length -Sum -Maximum
[PSCustomObject] @{
Path = $_.FullName
LastWriteTime = $Stat[0].Maximum
Length = $Stat[1].Sum
}
} | ConvertTo-Csv -NoTypeInformation
ってやると多少効率的かと >>562
なるほどな〜、余分な集計をする事になるとしても
measureを1回で済ませられれば効率的な可能性があるのか、
さらにパイプラインで列挙と集計が同時進行になる可能性もあったり?
と思い試してみたけど、残念ながらLastWriteTimeの-Sumがダメらしい。
-ea:SilentlyContinueなら?と思ったがLengthのMaximumしか出ない。
でもこのアイデアは使えそう。 >>564
ああなるほど、だから小細工してたのか、すまんかった
てか、初めからURL書いとけば良かったな
$Stat = $_ | Get-ChildItem -Force -Recurse -File | Measure-Object LastWriteTime.Ticks, Length -Sum -Maximum
[PSCustomObject] @{
Path = $_.FullName
LastWriteTime = [DateTime][Int64]$Stat[0].Maximum
Length = $Stat[1].Sum
}
https://stackoverflow.com/questions/66697384/measure-multiple-properties >>565
さも自分で考えたかのように書いて劣化パクリかよ PSv7だとmeasureに集計プロパティ使えるのか。
PSv5なので試せないのが残念。
速度の話が出てたからmeasureの速度がどんなもんか>>558で計ってみたら
自環境だと普通の実装(最高水位線と足し算)より7〜8倍くらい遅いわ。
まあ、標準コマンドレットのよくある結果だな…。 タスクマネージャの詳細タブからaudiodg.exeの関係の設定を変更する操作をスクリプトで書けますか? Get-Process "audiodg" | %{ $_.ProcessorAffinity = $コア数 }
$コア数は2のn乗で表したコア数の数
たとえば若い番号の3コアだけ割り当てたい場合は 0xf 上の3は4の間違い
もちろんタスクマネージャーをいじろうと思えばできるけど面倒 >>570
わからん・・・
2の4乗=16 != 0xf ?
4=2の2乗 だと 0x2 ?
コア数というよりフラグ?マスク?ってこと? comobjectでofficeを操作してるとき、
$xxx.Count() が 2なのに
$xxx[0] 範囲外
$xxx[1] 範囲内
$xxx[2] 範囲内
$xxx[3] 範囲外
みたいなアクセスになることがあるんやが
これはどう理解すればええんや? Excelってたしか値も書式もないセルはオブジェクト自体が存在しない扱いになるので、インデックスが0から始まるとは限らなかったはず
データが取れる前提で処理するとうまく行かない >>576
これかも
明日試してみるわ!サンクス!
>>577
これは怖いな
今回は関係なさそうだけど、心に留めておくわ、サンクス >>566
>>555からの流れ、色んな書き方があるんだなー、と非常に為になった $a = "abc::de/f/ghi/123jk"
$b = $a.TrimEnd("/")
をしても$bの出力が「abc::de/f/ghi/」にならないのですが、どこが間違っているのでしょうか? >>582
同じ勘違いしたことある
指定文字「を」末尾からtrimするのがTrimEnd
$a.TrimEnd("jk123")
Trimメソッドは正規表現使えないからreplaceステートメントをつかう
$a -replace "\w*$",'' >>583
ありがとうございます!
今回はreplaceを使っていこうと思います 11でもPowershell起動すると新しいのお試ししろとか表示されるけど5.1で十分だよなぁ
他の鯖系のベンダーのモジュールが5.1に対応しなくなったら考えるわ程度 >>586
前からexperimentalで有ったのは知ってたし、オプションだから嫌なら切ればいいんだけども…
cmdから呼ばれる想定のコマンドは引数処理に癖があるからといって、特定のプログラムのみ特別扱いするワークアラウンド的挙動にはちょっと賛同できない
ワークアラウンドというのはユーザーがやるものだ
pwsh側で個別対応をするとしても、ユーザーが期待する形式の引数を取って、コマンドの期待する形式に変換するラッパースクリプトを用意すれば済むだけの話
普段linux/macでpwsh使ってるから、どれ程の癖なのかは図りかねるが、 $obj.('行');
1. 上記を7.3で実行するとハングする。
2. 5.1や7.2ではハングしない。
3. $prop = '行'; $obj.$prop; でもハングする。
4. '行'が違う言葉だとハングしない。
5. $obj.行; だとハングしない。
バグ?バグなの?ゲイツに電凸していいの? あ環境はWindows11とmacOS13で再現してます。連投スマソ 589の条件4についてだけど、
$obj.([System.Text.Encoding]::UTF8.GetString((0xE8, 0xA1, 0x8C)));
でもハングして、UTF-8での先頭バイトが0xE8だった場合にハングするっぽい。
毎回ハングするのであんまり回数試してないけど。 まともにテストしてないか
変なメンテナが紛れてるか 7.30-preview.2 Core win10(en-US)だけど大丈夫な感じ
$gyo =[System.Text.Encoding]::UTF8.GetString((0xE8, 0xA1, 0x8C)))
$gyo
行
$trans=@{$gyo="go"}
$trans.$gyo, $trans[$gyo]
go
(まだ日本語IME入れてない新品なので行が入力できないのはご愛嬌)
属性/キーはハッシュ可能な任意のビット列で構わないはずなので、単にエンコルーチンの問題のはず、7.30-preview-2以降のgitレポの差分みては cx-fxは開始バイトだから安定リリースで出してたらマルチバイト圏壊滅してそうだが >>592-594 ども!
>>593 ありがとうございます。
preview.3 から preview.4の間でなんかあったとこまで突き止めましたが、
preview.3から5までのStart-PSBootstrapがバグっててビルドに予想以上に時間かかったからもう寝るお お巡りさんこの人でつ38909f7ee
でそのコミットの中身がこちら
Update .NET SDK version from `7.0.100-preview.2.22153.17` to `7.0.100-preview.4.22252.9` (#17061)
おふぅ。PowerShellのバグを追っていて大変なものを見つけてしまったーどうしよう? 以前は PowerShell の日本語ドキュメントのリポジトリが Github に置いてあったはずですが今は消えていますよね?
事情がよくわからないんですが、マイクロソフトとしてはコミュニティで日本語翻訳を運用しない (機械翻訳でやっていく?) ということなんでしょうか。
それはそれとして、諸事情でネットワーク接続できない場所で日本語ドキュメントを読みたいんですが
どこかでまとめてダウンロードする方法とかありませんかね? >>597
マイクロソフトにかきらず、英語以外の言語に翻訳することをみんなやめてしまっただけ。
ソフトウェアの更新スピードが速すぎて、ドキュメントを人間が翻訳する時間がない。 日本語にすると曖昧になっちゃうからな
英語で厳密に説明されたほうがいいだろうし、ソフトウェア技術者だったら英語は素養の一つだね >>599
ちょまどはイベントに参加したり楽しくやってる 文字列検索する時は、ラテン文字のキーワードが検索結果に埋もれない日本語ドキュメントのほうが便利 >>597
Get-Helpで取れる情報ならUiCulture指定してSave-Help
https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_updatable_help
それ以外ならGitHubから英語ドキュメント落としてきて機械翻訳かな
オフライン環境でスクリプト書く気はしないから必要なドキュメントは限られるのでは どうしてもドキュメントを日本語化してほしいなら16ビット時代みたいに
日本語版がリリースされる頃には英語版の新バージョンがリリースされている
みたいな事になってもおま国とか文句言わないようにしないとね
英語版が完成してからじゃないと翻訳作業を始められないんだから Google, DeepL, みらい翻訳
「みんなの自動翻訳@TexTra®」は、
国立研究開発法人情報通信研究機構(NICT)が開発した自動翻訳サイトです。無料
mt-auto-minhon-mlt.ucri.jgn-x.jp/
翻訳したいサイトのURLを入力するだけで、自動翻訳結果をエディタ上に再現 機械が無料で一瞬でそれなりの翻訳をしてくれる時代になったのに
わざわざ多ヵ国の翻訳チームを雇って変わり続ける膨大なドキュメントへの人件費を出す判断なんてできんだろなあ 私は現時点では PowerShell について全く知識を持たず、
入門的な資料を移動中の合間にタブレットコンピュータで読みたいと考えています。
(通信は出来ないので事前に入れておく必要があります。)
基本理念をわかれば個々のコマンドの資料はたぶん英語でも理解できると思うんですが
新しい概念そのものを英語で読むのはしんどいです。
オフラインで読みたいと思うと ePub (などの電子書籍形式) になっているとやりやすくて
そうするには元が Markdown なら一発で出来ると思ったんですが、
機械翻訳を通してその形に持っていくとなると面倒ですね。 Markdown は、HTML になるから、
「みんなの自動翻訳@TexTra®」で翻訳できるのでは?
翻訳したいサイトのURLを入力するだけで、自動翻訳結果をエディタ上に再現と書いてあるから、
ローカルPC にある、HTMLへのパスを入力すれば? >>608
翻訳できることにはなんの疑いも持ってないですよ。
コマンド一発で出来るツールはないので手間がかかると言ってます。 過去の公式日本語訳が出てきたとして、基本理念を理解したい人の役に立つレベルとは思えない
電子書籍買って読むほうがいい もしも古い翻訳テキストが手元にあるなら
それでいいんじゃね
新しい要素だけググって調べてブラウザ上でctrl+Sするなりして保存しておけば? 配列の要素を逆順にしたものを得たいのですが, …たとえば,
$a = @(10, 0, 5)
これに対して
$a[-1..-$a.Length] …とすれば,@(5, 0, 10) が得られて,
それで不満は無いのですが,何かもっとシンプルに書ける気がして.
(→ でもこれって $a[-1..0] とは書けないんですね.)
あるいは
[array]::Reverse($a)
とすることで,$a 自体が逆順の中身に変えられるのですが
でも $a自体は 変えたく無いのです
感覚的には
$a.Reverse() とか
$a | Reverse-Object みたいに書けたらいいのに
とは思うのですが(…そんなものは無い)
文字列だったら
[linq.enumerable]::Reverse("abcdef") で逆順を得られるのに
同じ場所に 数値の配列を書いて
[linq.enumerable]::Reverse(@(0,5,1,2))
…としても,何故かできない (なぜなのかはc#に勉強不足な私には分からず)
ってなわけで,別に困ってるわけでは無いのですが
もっと シンプルな書き方ってありますか >>614
とりあえず、$a[-1..-$a.Length]だと-1,0,1で並ぶから@(5,10,0)になっちゃうはず。
$a[$a.length..0] が正。
個人的にはlengthじゃなくてcount使ってほしい。
後はsort-object使うか。
$a|sort -des でいける。
ただし遅いので巨大配列には向かない。 >>616
$a[$a.Count..0] 言われてみれば! …これ使わせていただきます
なお,sort を使うと,どうしても数値でsortされてしまうので うまくいかない感じです
何の意味も無い基準でsortして(何の順番も変えないで) -desだけしてくれたらいいのですが >>614
[linq.enumerable]::Reverse([int[]]@(0,5,1,2))
LinqのReverseはこれで動く >>618 intの配列にcastってことなのか…半分くらいしか理解してませんが
ありがとうございます.
LINQは powershellだと 無理やり感があって,かえって使いにくい感じは ありますね Ruby なら、
reverse -> Array
reverse! -> self 破壊的変更
a = ["a", 2, true]
p a.reverse #=> [true, 2, "a"]
p a #=> ["a", 2, true] (変化なし)
a = ["a", 2, true]
p a.reverse! #=> [true, 2, "a"]
p a #=> [true, 2, "a"] 破壊的変更 きっと とても初歩的なことだとは思うのですが
$a = "abc"
$job = start-job { write-host $a }
receive-job -Job $job # → 何も出力されない
これって スコープの問題なんでしょうか
{ブロック}の中の $aの中身を "abc"にしたいのですが $using:a
About_Remote_Variables >>622 ありがとうございます
ブロックの中の $a を $Using:$a と書けば望む動作になりました
まぁ、何でusingって名前なんだろ?とか
Remote Variablesとは言うけれど別にリモートじゃないし(?)など
まだ不思議な感じは残りますが…もうちょっと調べたり勉強してみます $a = "abc"
$job = start-job { param($str); write-host $str } -Arg $a
でも 受け渡せるんですね。 Start-Jobでスクリプトブロック実行すると
別プロセスのpowershell.exeが起動してそっちで動く。(少なくともPSv5.1では。)
イメージとしてはコンソールや.ps1から「powershell.exe -f 他スクリプト.ps1」で
他プロセスを動かすくらいに別スコープだと思ってればいいと思う。 >>599
マイクロソフトのサポートにはとんでもない質問が大量に押し寄せる。
Windows Serverが起動しなくなった。電源が入ってないけど、Windowsのバグに違いないやら、しつこい嫌がらせやら、女に変なことを聞く変態やらと3万円も払って電話してくる。 PowerShellのバージョンがわかりませんのでどうすればいいですか?
こんなのを3万円も払って教えてもらうのが日本人 一時片手間にカスタマサポートやってたことあるけど結構トンデモ問合せは多い
いろいろ聞いて行ったら他社の製品の問合せだったなんてオチすらあるし >>625 そういうイメージ…ということでわりと納得.
同じことですが…では、ブロックの中で処理中に 変数に何かを入れても
それは、receiveするまでは 取り出せないってことか… functionの中でhashtable @{}を作成してその中にウィンドウと紐付いてるハンドルオブジェクトやらを入れて返して
functionの呼び出し側で使おうとしたら無効なオブジェクトやら何やらのエラーが出てまともに使えなかった
PSObjectに変換して返したらエラーは出なくなったがこれ何だろう
怖すぎなんだが 参照型/値型とかその辺の理解は問題ない?
とエスパーしてみる 紐付けてるオブジェクトやらは.NETの参照型ね
値型だったら恐らくこの問題は起きてないだろうし
PSCustomObjectのプロパティとhashtableの値への紐付けでオブジェクトの生存期間に差異があるようにしか見えないから
functionから戻る時に何か想定外な事が起きてるんだろうなあ コマンド・プロンプトも一切つかったことない状況から
powershellの勉強最近始めたけど難しいね
先ず参考書籍少なすぎ
何から手を付けたらいいのか全くわからん
先輩諸兄はどんな感じで習得していったの? 必要に迫られて色々とネットで調べて解決策を探し回る
そのコードから理解できない部分や言語の基本を調べる(変数や表示の仕方とか色々と)
という泥縄式だな ネットしかないのか、仕方ないな、、、
しばらくは苦しみながら覚えるしかないかぁ Get-Help about_
で出てくるのを一通り読んどきゃ何も苦しむことなんてないだろ ある程度使えるようになってから書籍買って読んだら
「大体全部知ってるわ」ってなったから
ネットだけでもいけるだろ 他の言語と違って思い込みて書かれた間違った記事が多いから警戒すべし ほかの開発言語やシェルプログラミングにまったく疎い状況からPoweshellで入門してゴリゴリ使いこなしてやろうという路線は正直筋が悪いと思う
とはいえ勉強のためにPythonあたりの入門書をやれとも言いづらい
やはり泥縄式かな >>639
一応VBAとGASが多少できるなったから他の言語も余裕かな、っておもって
PowerShellに手を出したら苦戦してる感じ
一通り基礎を覚えたら実践的に色々と試してみたいけど
powershellは色々覚えることが多すぎてメンドイ、、、 変数?配列?何それ状態から始めてる初心者だけど基本的な用語がわからないから検索にも苦労する
セオリーもわからないから無駄にあれこれやってあとはコメント書きまくってグチャグチャになってる PythonもJavaも全くコード書けないノンプログラマだけどPowerShellは分かり易い気がする 素人だけど、「PowerShell実践ガイドブック」っていう本は、素人には理解しにくい仕様とかを理解するのにとても役に立った
ただ、いろいろ冗長でちょっと読みづらい本ではある PowerShell上で cmd /C xxxx を使うのが最善という結論に到達する
こういうのでいいんだよ的な ヘルプが出来が良いので何も要らない気はするけど
ハック的なモノや中でどう動いてるとかはpowershellexplained、実用的な書法はPowerShellGetで人気のあるやつ読むとか PowerShell は配列周りがトリッキーなのを除けば比較的まともな言語だと思う 覚え始めは Microsoft docs を探し、それでわからなければ個人の解説記事を探した
スクリプトを書くようになってからは about_ から知りたいことを追いかける事が増えた
上でも名前が上がった「PowerShell実践ガイドブック」は、ある程度できるようになってから読んだが
何もわからない状態で読むにも良いと思う
第2章までで基本的なことが身につく パワーシェルの勉強始めたいんですが、学習に良いサイトありませんか? >>648
実はこのスレだったりする
1つのサイト覗くよりたまにぜんぜん知らん知識が入ってくる
過去ログおすすめ あと間違った情報書く奴には必ず突っ込み入るから間違えたまま覚え事故も起き難くなる仕様だと個人的には思ってる powershell何某でぐぐって出てくる日本語の情報はなぜか間違ってたり思い込みで書かれた記事が放置されてて悲しい
情報源としてはstackoverflow辺りをまず探すのが安定
Microsoftの知りたかったことの全て系は役には立つけど知りたい事全てを補完できるわけではない リリース当時は学生だったからPIAをむさぼり読んでたな、楽しい本だった
挙動で間違いやすいのは(スコープを除けば)基本パイプ周りだから、
パイプ使わないスクリプトを書いてけば初手で躓く要素は少ないと思う >>653
シェルスクリプトを知っているのが前提だと思っていたが? パイプで間違う要素なんてあったっけ?
むしろ配列まわりの方が間違いやすい気がするが... 前提は知らんけど、配列回りで間違えるのがパイプ使ってる時では? >>656
いやパイプ関係なく PowerShell の配列は色々トリッキー
例えば複数のオブジェクトを配列で返すコマンドレットが要素が1つだけだとオブジェクト自体を返したりするとか
https://qiita.com/hitsumabushi845/items/fe4219ba9daa34f541c2
switch文に配列与えたら各要素を順番に適用する(要は勝手にループする)とか
https://step-learn.com/article/powershell/076-switch-loop.html >>657
まさに前者をパイプ周り(のための)の仕様だって認識してる
カンマ演算子の使い方は知らないとできないけど、型指定しない変数に代入して原因がわからないってことはないでしょ
後者はforやforeach省略出来て便利ってだけで、トリッキーだとは思ったことないわ switchの評価式に配列をぶち込む発想は他の言語経験有りなら起きないから無害だけど
function戻りの配列の扱いは慣れてても混乱するから特殊な事情が無い限りPSObjectや別のコンテナに入れて返す(脳死) どなたか助けてください。相談です。
一つのファイルに置換したい複数の数列(0.005→0.000、0.006→0.001、0.007→0.002、etc‥)が存在した場合、うまく自動で全て置換する方法はないでしょうか?
下の置換のコマンドを繰り返し使用してるのですが明らかに非効率で何かうまくできないか考えてます。
(Get-Content ファイル名) | foreach { $_ -replace "置換前","置換後" } | Set-Content ファイル名 >>660
$hash = @{ 0.005 = 0.000; 0.006 = 0.001; 0.007 = 0.002 }
$hash[0.006]
とすると 0.001 が返るから、"置換後" にあたる部分を $hash["置換前"] とすればいい。
詳しくはハッシュとかハッシュテーブルでググれ ver6.0以降だとスクリプトブロック使えるから、一応こんな感じで一度にできることはできる
"対象の数値" -replace "^[-+]?[0-9]+[.]?[0-9]*", { [decimal]$_.value - 差分の数値 }
数字の足し引きならCSVデータとかで読みこんで処理した方がいいとは思うけど >>661,662
すげー。ありがとうございます。 0.005を足した数値にしたいと書いてないのが不思議
質問者は聞き方がわかっていない ちなみに、v5でも[regex]::Replace()のMatchEvaluatorにスクリプトブロックを渡せるから
>>662より手軽さが劣るけど同様の事ができる。 サブディレクトリ以下の全てのファイルに対し、ゾーンIDの削除をしたいのですが、
各ファイルのゾーンIDは
Get-ChildItem -Recurse -File | ?{
$_ | Get-Item -Stream Zone.Identifier -ErrorAction Ignore;
} | Remove-Item -Stream Zone.Identifier;
に書けばできるみたいです。
powershell の勉強のため、下記のような書き方だと、どのように書けばできるのでしょうか?
$itemList = Get-ChildItem $targetFolder -Recurse;
foreach($item in $itemList){
Get-Item -Stream Zone.Identifier -ErrorAction Ignore;
} >>666
こういうこと?
foreach($item in $itemList){
if (Get-Item -LiteralPath $item.FullName -Stream Zone.Identifier -ErrorAction Ignore) {
Remove-Item -LiteralPath $item.FullName -Stream Zone.Identifier
}
}
もちろん$itemはLiteralPathの代わりにパイプでオブジェクトごと渡してもいいと思う >>667
ありがとうございます。
勉強になりました。 例えば、Ruby で、再帰的にフォルダのサイズを求めてみると、
require 'win32ole'
fso = WIN32OLE.new( 'Scripting.FileSystemObject' )
# 絶対パスのディレクトリ名の後ろに、* を付けること!
# . で始まる、隠しフォルダ・ファイルを除く。
# /**/* で再帰的に、以下の全てのフォルダ・ファイルを走査する
dir_path = "C:/Users/Owner/Documents/**/*"
target_dirs = Dir.glob( dir_path )
.select { |full_path| File.directory?( full_path ) } # フォルダのみ
.each do |folder|
folder_obj = fso.GetFolder( folder )
puts File.expand_path( folder_obj.path ) # \ を、/ に変換する
puts "#{ folder_obj.name } : #{ folder_obj.size }"
end
出力
C:/Users/Owner/Documents/a
a : 14231
C:/Users/Owner/Documents/a/b
b : 4666
# next で、次の繰り返しに進む事もできるが、
# select みたいなフィルターで絞り込む方が、可読性が高い
Dir.glob( dir_path ).each do |full_path|
next unless File.directory?( full_path ) # フォルダだけを処理する
puts full_path
end Tree /fとget-childitem select-object Full name,を組み合わせたデータがほしいのですが、ご存知の方、ご教示願います。 >>670
名前の通り再帰処理でフォルダのツリーデータ構造を作ってから出力する事になる。
powershellの関数呼び出しは100ぐらいのネストでスタックオーバーフローするので、
ある程度動作確認が出来たら再帰処理を配列とループに変換するか、
C#なりで書き直す必要があるかも。 >>670
https://www.powershellgallery.com/packages/Show-Tree/1.0.0
146行目を書き換え Write-Output ("{0}+---{1}" -f $start, ($PSDriveFullPath)) >>672
ありがとうございますm(_ _)m。できました。スクリプトの実行が無効になっているため、読み込むことができません。と出ましたが、ポリシーを変更してできました。
>>671
ありがとうございます。制限があるのですね。 @("2023/01/01,123","2023-01-02,abc","2023 01 03,あいう") | convertfrom-string -delimiter "," | sort-object p1 -descending | convertto-csv -notypeinformation
"yyyy/MM/dd"っぽいと勝手に日付時間の形式に変換されるのですがされないようにできますか?
windows10 PSVersion 5.1.19041.2364 @("`"2023/01/01`",`"123`"","`"2023/01/02`",`"abc`"","`"2023/01/03`",`"あいう`"") | `
convertfrom-string -delimiter "," | sort-object p1 -descending | foreach-object {"$($_.p1),$($_.p2)"}
こうすれば出来たっぽいけど何かめんどくさい >>674
日付でソートするならばConvertFrom-Stringによる日付処理のままDateTime型で扱うのが正しいのでは? csv出力する際に "2023/01/01" が "2023/01/01 00:00:00" となるのを避けたいということです
ソート部分は別の処理をするかもしれないです
わかり難くてすいません
あとは tostring() で変換し直すかくらいでしょうか >>674
676 の方針で書き換え量少なめパターン
@("2023/01/01,123","2023-01-02,abc","2023 01 03,あいう") | convertfrom-string -delimiter "," | % { $_.P1 = $_.P1.ToShortDateString() ; $_ } | sort-object p1 -descending | convertto-csv -notypeinformation
Convertfrom-String を使いつつ変換したくないという裏には深い事情がありそうだが
その深い事情を無視していいなら新しくオブジェクトを作るのが楽かな
@("2023/01/01,123","2023-01-02,abc","2023 01 03,あいう") | %{ [PSCustomObject] @{ 'Date'=$_.split(',')[0]; 'content'=$_.split(',')[1] } } 自分もConvertfrom-Stringさえ使わなければ楽だと思うが、
当初の質問通りConvertfrom-StringでDateTime型への自動変換を避ける方法、
という事なら
$a = @("2023/01/01,123", "2023-01-02,abc", "2023 01 03,あいう")
$t = @"
{p1*:2023/01/01},{p2:123}
{p1*:*},{p2:*}
"@
$a | ConvertFrom-String -TemplateContent $t
p1 p2
-- --
2023/01/01 123
2023-01-02 abc
2023 01 03 あいう >>678−679
ありがとうございます、参考にさせて頂きます
convertfrom-string を使っているのは前に使って動いてるからヨシッ!の精神と圧倒的な知識不足の為です PSCustomObject なんて便利なものがあるんですね
おかげで Convertfrom-String も使わないで済むようになり
日付の自動変換もされなくなりました、ありがとうございました 本来、肩こりを和らげるマッサージの福利厚生の充実よりも、肩こりしない環境にすることが重要なわけだが、
PowerShellやってる人は、肩こりを和らげるマッサージを喜ぶ傾向が顕著 肩こりしない環境ってなんだろ
コマンドプロンプト? rubyってことかもな
これを言ったのがいつも突然出てくるruby野郎だったら間違いなくrubyだと言える 肩こりにはCUIはダメ
ぐいぐいするのが効くでしょう(秀逸) Ruby では「2023/01/01, 2023-01-02, 2023 01 03」の内、
最後の形式だけ、Date.parse で日付オブジェクトに変換できない
日付オブジェクトに変換せず、文字列のままソートするのが簡単
date_texts = %w(2023/01/03 2023/01/01 2023/01/02)
p date_texts.sort # 日付の文字列でソート
#=> ["2023/01/01", "2023/01/02", "2023/01/03"]
# 要素内に空白を含むので、\ で要素内の空白をエスケープする
date_texts = %w(2023/01/03\ あいう 2023/01/01\ 123 2023/01/02\ abc)
p date_texts.sort # 全体の文字列でソート
#=> ["2023/01/01 123", "2023/01/02 abc", "2023/01/03 あいう"] Ruby で仮に、2列のCSV テキストとみなした場合でも、
sort_by で任意の列のソート順で、行をソートできる
require 'csv'
input = <<"EOT"
2023/01/03 あいう
2023/01/01 123
2023/01/02 abc
EOT
options = { col_sep: " " } # 空白区切り
p input_ary = CSV.parse( input, options ) # 2次元配列
#=> [ ["2023/01/03", "あいう"], ["2023/01/01", "123"], ["2023/01/02", "abc"] ]
# 日付列でソートする
p result_ary = input_ary.sort_by{ |row| row[ 0 ] }.map( &:itself )
#=> [ ["2023/01/01", "123"], ["2023/01/02", "abc"], ["2023/01/03", "あいう"] ]
# 2次元配列を、CSV 文字列に変換する
puts csv_str = result_ary.map( &:to_csv ).join
カンマ区切りで出力
2023/01/01,123
2023/01/02,abc
2023/01/03,あいう Ruby の日付オブジェクトには、数十種類の書式がある
require 'date'
# デフォルトの書式は、下と同じ
puts date = Date.parse( '2023/01/01' )
#=> 2023-01-01
# %F: %Y-%m-%d と同等 (ISO 8601の日付フォーマット)
puts date.strftime( '%F' )
#=> 2023-01-01
# %T: 24時間制の時刻。%H:%M:%S と同等
puts date.strftime( '%F %T' )
#=> 2023-01-01 00:00:00 目的と手段があべこべになってるって意味だよ、察しろよ 確かにRubyを使うこと自体が目的になってる奴いるよな Excelを操作しようとしたら酷く遅い。
これは工夫が足りない感じ?
やりたいのは3000行、100列ぐらいに関数が詰まってて、その中でエラーとなってるセルを見つけること。
関数が別のブックを参照してて、その別ブックは日々自動生成されるからその生成されかたによってはどうしてもエラーになってしまう。
VBAでも出来るけど、他と併せて考えるとPowerShell向きの処理だから、これで始めたのに。
PowerShellからVBAのプロシージャ呼び出せば、この部分の処理は一瞬だけど、それは本末転倒だし。 >>693
COMのIDispatch経由だからVBAと比較すれば当然遅くなるよ
一個一個のセルを見て回るのなんかは特に遅い
powershell自体も遅いから遅さはさらに加速する
ワークブックを開けてるならCOMからVBAコードを動的に流し込んで処理させた方が全然速いかもしれない
CodeModule.InsertLines辺りでぐぐれば出てくると思う 全セルまとめて取ればどんな言語でも早いんじゃない? 数式のチェックをするということならusedrange.formulaとかで二次元配列に入れてしまえば速いだろうね セルの値をチェックしたいのか数式をチェックしたいのかもわからんしそもそも既に作ってあるならその遅い部分のコード晒せばいいのに
としか思わん PowerShellでRangeに対してforeachを使ったら糞遅かったが、Range.Cellsに対して使ったら爆速でした。
VBAで.Cellsを付けないことは無いが、PowerShellだと書き方が変わるから気付かんかった。
ソースは仕事で晒せないが、記憶を頼りに再現したのを後で書くよ。 やりたい内容によってはImportExcelとか使うといいかもしれない Excel操作は真面目にやるとCOMの参照の管理と解放が大変で避けちゃう。
完全に自分用なら雑でもいいんだけどさ。
VBScriptくらいに気楽にやらせて欲しい。 あららSnoverさん去年退職しちゃったのか、、、
言語的には成熟してるし問題はないんだろうけど、残念だな >>698
素直にExcel VBAを書いた方が安全だよ。 gci -recでレジストリ検索出来るの便利だなって一昨日思った 大規模な PowerShell モジュールは Install-Module での導入がオススメです
https://jpwinsup.github.io/blog/2023/02/27/UserInterfaceAndApps/PowerShell/PowerShell-ImportModule-FunctionOverflow/
Windows PowerShell では、 1 セッションのうち利用できる関数 (Function) の数の上限を変数 $MaximumFunctionCount にて制御しており、既定では 4096 となります。
Import-Module にて PowerShell モジュールを導入しますと、この $MaximumFunctionCount で管理する関数の数にカウントされ 4096 を超えた場合にエラーが生じます。
Install-Module では、本事象は発生しませんので、Install-Module を、ご利用いただくことを推奨いたします。
単機能のモジュールであれば、今回のような制限が生じるほど大規模な関数 (Function) 数とならないですが、クラウド製品に対し提供されるモジュールは、大規模な関数数となる傾向がございます。
クラウド製品に対する PowerShell モジュールのご利用にはインターネット (オンライン) への接続が必須となりますため、Install-Module も利用可能でございます。 vscodeのプラグインどうにかしてくれないかな
せめて参照関連はちゃんとして欲しい PowerShellの構文が分からなくなったときに今話題のChatGPTで質問してみたら
的確な回答返ってきてすげぇ助かったわ。もうパソコン教室は廃業だろこれ ai のコード生成って結構すごいよね
コパイロット入れてるんだが、マジで打とうとしたコード先読みしてくる
インテリセンスみたいな数文字打って残りの補完じゃなくて、まるまる予測してきて更に当たってるっていう ここでいいですか
ttps://qiita.com/Midoliy/items/a033b763399c242dc5c5
C#をスクリプト言語として利用する方法
PowerShell 7.3.3 で、dotnet tool install -g dotnet-script を入力してもエラーになります↓
C:\Users\UserName0\AppData\Local\Temp\47744ec9-ca71-4312-b0e8-3f8bd18d5776\restore.csproj : error NU1101: パッケージ dotnet-scri
pt が見つかりません。ソース Microsoft Visual Studio Offline Packages には、この ID のパッケージが存在しません。
ツール パッケージを復元できませんでした。
ツール 'dotnet-script' をインストールできませんでした。この失敗は次の原因で生じた可能性があります。
* プレビュー リリースをインストールしようとしており、--version オプションを使用してバージョンを指定しなかった。
* この名前のパッケージが見つかったが、.NET ツールではなかった。
* 恐らくインターネットの接続の問題で、必須の NuGet フィードにアクセスできない。
* ツールの名前の誤入力。
パッケージの名前付けの強制を含む他の理由については、https://aka.ms/failure-installing-tool にアクセスしてください >>707
コパイロットとやらはインタラクティブシェルでも使える?興味あり
gnureadlineうんこpsreadline最強と思ってたら思わぬ伏兵が…
bingのchatgptが話題になってるし、標準で付いてもおかしくないけど インタラクティブ(履歴)/スクリプトでもヒューリスティックにコンテキストを読んでくれるのは新しいね、もはや補完ではない気がするが
ところで-UseFussyが超便利 f1で直近コマンドの、Alt-hで直近パラメータのヘルプがコマンドラインを汚さずにチラ見出来るけど
常時表示しておきたい コマンドプロンプトのstartコマンドのように
新しいウィンドウを作成せず、使うプロセッサを指定して起動するにはどうすれば良いですか Add-Type によって、自作のクラスを使う処理を書いて、一応ちゃんと動くのですが
同じことを 何度もやろうとすると 二度目以降は「The type 〜 already exists.」と出て止まってしまいます.
そこで「既に そのタイプが存在しているかどうか」をチェックしたいのですが、これってどう書くんでしょうか >>717
こんなん
Add-Type @'
public class MyClass {
public void test() {
}
}
'@
if ("MyClass" -as [type]) {
"MyClass is exist"
} >>719
>新しいウィンドウを作成せず
という指定が抜けてね? >>717
単純に try { [クラス] } catch { Add-Type 〜 } とか、知らんけど
>>719
Start-Processを使わない場合のように新しいウィンドウなしで起動したいです >>722
最初はそれでいいと思ったんですが、コンソールの取り合いになります
(Start-Process netsh.exe -NoNewWindow とかで試すとわかりますが、くれぐれもご注意を)
取り合いにならないように -Wait も指定して
(Start-Process netsh.exe -NoNewWindow -Wait -PassThuru).ProcessorAffinity = xxx
とすると、-Wait が効きすぎて ProcessorAffinity をセットできないという罠 つまり.NETのProcessorAffinityは存在するプロセスにしか適用できないから無理でいんじゃね
知らんけどWin32APIとかで別の方法を探った方がいいんじゃね たとえばWin32APIのCreateProcessにCREATE_SUSPENDEDというフラグがある
プロセスをサスペンド状態で作成してaffinity設定してからResumeThreadで開始
これでいけるんじゃね Start-Jobの中で実行したら上手いこと裏でやってくれないだろうか Start-Process -NoNewWindow cmd.exe "/c start /affinity xxx /b foo.exe"
これくらいしか思い浮かばなかった 定義が長くなったからこっちに貼り付けたよ
https://ideone.com/LOSuzD
使い方
bool [Win32API]::CreateProcessWithAffinity(appname, cmdline, affinity)
affinityはプロセスに直接設定するAPIが見つからなかったのでGet-ProcessをResumeThread前に呼び出して指定してる
サンプルはcmdを呼び出してpingをlocalhostに10回打ってる間にプロセス名とaffinity値を出してる Start-Process -NoNewWindow -Wait cmd.exe "/c start /affinity xxx /b foo.exe"
こうだった 寝ぼけてた。コールバックの部分下だけで良かったわ
System.Diagnostics.Process.GetProcessById(pInfo.dwProcessId).ProcessorAffinity = (IntPtr)affinity; でもう一箇所、appnameに$nullを指定してもC#側型宣言で""に変換されてしまうので、CreateProcessの直前に下を追加しとくとcmdlineだけで動く
if (appname == "") { appname = null; } これパイプすればいいんだよ
ポイントは () を使わないこと
(Start-Process).ProcessorAffinity = xxx は NG
Start-Process | ForEach-Object {} で OK
(Start-Process) | ForEach-Object {} は NG
& { Start-Process } | ForEach-Object {} でも OK Start-Process cmd.exe -ArgumentList '/c echo hello world & ping 127.0.0.1 -n 10' -NoNewWindow -PassThru | %{ $_.ProcessorAffinity = 1; $_ | select Name, ProcessorAffinity } Start-Process cmd.exe -NoNewWindow -PassThru | % { $_.ProcessorAffinity = 1 } だと困る
Start-Process cmd.exe -NoNewWindow -PassThru -Wait | % { $_.ProcessorAffinity = 1 } か
Start-Process cmd.exe -NoNewWindow -PassThru | % { $_.ProcessorAffinity = 1; Wait-Process -Id $_.Id } 717です. 反応してくださったかた ありがとうございました
>>718
if ("MyClass" -as [type]) → なるほど!…これでした!
>>721
私も,とりあえずは
try{ [MyClass] >$null } catch{ Add-Type -Path "〜.cs" >$null }
で 済ませていたのですが
例外に たよる書き方は,なんとなくカッコ悪い感じがして(笑) >>716
(Start-Process -FilePath 〜〜〜 -ArgumentList 〜〜〜 -WindowStyle Hidden -PassThru).ProcessorAffinity = 1 それでは Start-Process を使わない場合と違って入力も出力もできない あ〜、
> コマンドプロンプトのstartコマンドのように
> 新しいウィンドウを作成せず、使うプロセッサを指定して起動するにはどうすれば良いですか
というか
新しいウィンドウを作成せず、
コマンドプロンプトのstartコマンドのように使うプロセッサを指定して起動するにはどうすれば良いですか
という感じか。であればこれまでに出てた回答の方が正しいね。
ほぼ同じだけど自分なら
$proc = Start-Process -FilePath 〜 -NoNewWindow -PassThru; $proc.ProcessorAffinity = 1; $proc.WaitForExit();
みたいにするかなぁ。(でもStart-Processじゃなく小回りのきくProcessStartInfoを使うかな?) 質問です。
外部コマンドの標準出力やエラー出力を一緒に変数に入れたいのですが、
$result=外部コマンド.exe 2>&1
この式で一見動作はしてるようのですが、外部コマンドからエラー出力があった場合に赤い色が付き、powershell的なエラーメッセージも追加されてしまいます。
意図としては色とか追加メッセージとかは不要で、純粋に外部コマンドの標準出力やエラー出力を一緒に変数に取り込みたいだけなのですが、
そういう場合どう記述したら良いでしょうか。 外部コマンドの引数が不要またはシンプルなら、
簡単で分かりやすいのはcmd上で標準出力にする方法
$result=cmd /c "外部コマンド.exe 2>&1" >>741
cmd脱却を考えているので、できればpowershell流?の書き方があればお願いいたします >>742
Powershellでcmdを使いこなす技術を鍛えたほうが幸せになれると思うよ ためしにChatGPTに質問してみたら以下の回答でした
質問「powershell上から外部コマンドを実行し、その標準出力とエラー出力を、powershellによる出力の加工を抑止した状態で1つの変数に入れたい」
$output = & <コマンド> 2>&1 | Out-String
Out-Stringは盲点でした。一応文字列として取得できているのでこれでいいのかな PowerShellはあてにならないからcmdに頼ることも多いよな
Write-Host Test 1
New-Item -Path target1 -ItemType Directory
New-Item -Path junction1 -ItemType Junction -Value target1
Write-Host Test 2
New-Item -Path test2 -ItemType Directory
Push-Location -Path test2
New-Item -Path target2 -ItemType Directory
New-Item -Path junction2 -ItemType Junction -Value target2
これが失敗するなんて想像してなかった >>745
PowerShell5.1だと失敗しないな
7.3は駄目だった ターゲットのパスを絶対パスにすれば作れる
New-Item -ItemType Junction can't create relative link #18251
https://github.com/PowerShell/PowerShell/issues/18251 ジャンクションなら絶対パス必須でもいいけど
シンボリックリンクでは相対パスが使えないと不便
>>745 のテストをシンボリックリンクに変えてもやっぱりおかしい
ターゲットがディレクトリなのにファイルのシンボリックリンクになる
条件次第で逆にすることもできる
タイプ間違いだと補完や削除をするときに困るんだよな
だから最初からcmd.exeでmklinkしてる Target type detection (file/directory) for relative symlinks is still broken, even on Windows #15235
https://github.com/PowerShell/PowerShell/issues/15235
これか?
2年前に立ったissueなのにまだ直ってないみたい >>739
あの〜、コマンドプロンプトのstartだと1行の
start /B /AFFINITY 1 cmd.exe
のように「新しいウィンドウを作成せず、使うプロセッサを指定して起動する」には
小回りのきくProcessStartInfoを使うとどう書くの? 例示ではプロセス起動・Process型オブジェクト取得にStart-Processを使ったけど
>>739は普段はProcessStartInfo使ってるってだけじゃないの。
私も引数あるときはStart-Process(-ArgumentList)避けてProcessクラス使う。 PowerShellってWebスクレイピングには向いてないですか?
Pythonで作った方がいいですか?
PowerShellは職場用のスクリプトを何個か作ったりして少し分かるのですが、Pythonはまったく不慣れなので迷ってます Windowsに限ればスクレイピング以外にもブラウザに直接細工する手段が充実してるからライブラリ頼みのpythonより向いてるとも言える >>753
>>754
ありがとうございます
PowerShellでやってみようと思います PowerShellでPersonal Communicationsを操作しようと思い
以下のサイトを参考にしようとしたのですが
https://www.tekizai.net/entry/2021/10/04/063000
64bit版のPowershellでは出来ないようです
64bit版でも動かせるように変更はできないでしょうか? 64bit環境用のPersonal CommunicationsのOCXやらが無い場合は32bitのpowershellからCreateObjectするしかないとは思うけど
そのサイトのVBA版では環境に関する言及がないね
32bit版Officeを使っているという前提で書いてるのかもしれないが試してみないと判らないね すいません、当方SEで技術的な質問です
administrator権限のユーザーでLinuxサーバーからパスワード認証でなく、秘密鍵と認証鍵の認証方式でwindowsサーバーにSSHを掛けたいのですが、administrator権限のユーザーですと、パスワードを聞かれてしまいます
他の権限のユーザーは問題無く認証されます
administrator権限では認証方式のSSHは使えないのでしょうか? >>759
ありがとうございます
明日、業務で試してみます Windowsのディスプレイ設定で拡大率を100%以外にしてると
フォームの文字がぼやけるんだけど、なにか解決策はありますか?
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.text= "タイトルはぼやけない"
$label = New-Object System.Windows.Forms.Label
$label.Size = New-Object System.Drawing.Size(300,20)
$label.Text = "ディスプレイ拡大率が100%以外だと文字がぼやける"
$form.Controls.Add($label)
$form.ShowDialog() その辺て外人もあまり正解に辿り着いてない箇所だな
俺も辿り着いたとは言えんけど面倒だった powershellじゃなくてWindowsFormsの問題でしょ
「WindowsForms ぼやけ」で検索したらいくらでも出てきたけど ちょっと意識して組めばできなくはないから環境を変える程でもないな c:\aaa\bbb\ccc\hhh
c:\aaa\ddd\eee
c:\aaa\fff\ggg(以下続く)
というフォルダ構造があった場合、ccc(サブフォルダhhhも含む)、eee、gggのフォルダを別のフォルダにコピーしたいんですがうまくいきません。
chatGPTに聞いたところ ($rootFolder=c:\aaa、$targetFolderはコピー先)
$targetFolders = Get-ChildItem $rootFolder -Recurse -Directory | Where-Object { $_.FullName -like "$rootFolder\*\*\[ceg]" }
となり、少し変更して
$targetFolders = Get-ChildItem $rootFolder -Recurse -Directory | Where-Object { $_.FullName -like "$rootFolder\*\*" }
としてみたんですが、これだとcccフォルダがコピー先に存在していた場合hhhフォルダがcccフォルダとは別にコピーされてしまいます。
同じフォルダ名があった場合サブフォルダの処理を飛ばしてフォルダ構造したままコピーする方法はないでしょうか。 フォルダ構造したまま→フォルダ構造を維持したまま
失礼しました。 ・同じフォルダ名があった場合サブフォルダの処理を飛ばしたい
ってう制約を加えてchatGPTに聞いたらいいんじゃね >>770
試してますがうまくいきませんね。aaaやbbbが例えであることをうまく理解してくれなくて、
全てのフォルダ名を手入力する必要があるコードしか作ってくれません。○や△みたいな記号に置き換えても同じ。
get-childitemで特定の深さ以下のフォルダ名を取得することができればうまく行きそうですが、
-depthは特定の深さ「まで」のフォルダを検索するオプションですよね?
特定の深さ以下のフォルダを検索する方法はありませんか? 一発でrecursiveでやるのを諦めて泥臭く2重なり3重なりの繰り返し処理にして
自分でフォルダを掘り下げていけばいいんじゃないの >>771
「特定の深さ以下」ではなく「特定の深さ直下」を対象としたいんだよね? >>768 はネタかもな
コピー先に何があるのかチェックしないという発想は、まったく理解できない。
初心者なら前提条件という概念がないのはわかる。
先にあったらこうする、そうでなかったらこうするなどの条件分岐がないなら、強引にやればいい。
そもそもROBOCOPYコマンドでできることをやろうとしているのは、これ学校の課題なのかなと思いました。 深さ3のディレクトリをそのままコピーすりゃいいだけじゃないの? >>774
そうなんですが、>>768だとd:\コピー先\ccc\hhhとしたいのにcccフォルダがすでにあると
d:\コピー先\ccc
d:\コピー先\hhhになっちゃうんですよね。
>>772の方法か、もしくは>>776robocopyとforeachで何とかできるか? とりあえず自分であがいてみます。 入出力をちゃんと定義できてないからおかしな事になる初心者あるあるだな 特定の深度だけ処理してみた
※$Sourceはフルパス指定であること
param(
[string]
$Source,
# $Sourceからの相対深度
[int]
$RelativityDepth
)
# パスを\と/で区切って配列化
$SourceDirSplit = $Source.Split([System.IO.Path]::DirectorySeparatorChar).Split([System.IO.Path]::AltDirectorySeparatorChar)
foreach ($TargetDir in @(Get-ChildItem -LiteralPath $Source -Recurse -Directory))
{
# パスを\と/で区切って配列化
$TargetDirSplit = $TargetDir.FullName.Split([System.IO.Path]::DirectorySeparatorChar).Split([System.IO.Path]::AltDirectorySeparatorChar)
# 指定深度にあるDirを処理
if ($TargetDirSplit.Count -eq ($SourceDirSplit.Count + $RelativityDepth))
{
# 一致したディレクトリを返す
$TargetDir
}
} Start-ThreadJob や Register-EngineEvent のスクリプトブロックの中で
キャプチャされずにWrite-Output 相当の出力をする方法はないでしょうか
パイプラインに流したいので Write-Host ではなく Write-Output したいです
別のプロセスを経由する方法は思いついたのですが残念過ぎますし
ForEach-Object -Parallel のようにキャプチャされなければ良いのに
function hogepiyo {
begin { 処理本体はここで Start-ThreadJob しておく }
process { … }
end { … }
clean { … }
}
なんちゃら | hogepiyo | ぽげむた
のようにしたくて考えてます
要は入出力と処理を非同期にできれば他の方法でもありがたいです PowerShellでフォーム作るの割と苦痛なんだけど何かデザインモードとかないの? Where-object多様するスクリプトに数万行のcsv食わせたら処理に1時間くらいかかる…
大量のデータ処理はWhere-object使うなってみかけたけど使わん方がいいのか 件数が少ないことが確実な時しか使わない。
スクリプトだとほとんど foreach(){} 使ってる。
パイプライン処理したい場合でも &{} や .{} や function の process{} あるいは filter。 >>784
PowerShell スクリプトのパフォーマンスに関する考慮事項
ttps://learn.microsoft.com/ja-jp/powershell/scripting/dev-cross-plat/performance/script-authoring-considerations?view=powershell-7.3 >>782
出力がコレクションにためられて Receive-Job が必要になるのを回避したい
Start-ThreadJob の -StreamingHost オプションの Write-Output 版な感じ
そんなオプションはないから回避方法を知りたい
Start-TheadJobだけでなくイベントハンドラから出力する場合も同じ
イベント飛ばせばいいかと思ったらハンドラがジョブ扱いされて頭抱えた
どうすれば Receive-Job を必要とせずに Write-Output 相当の出力ができるのだろう >>785
>>787
40万行処理するのに3時間かかったから作りなおすわ… >>788
Jobである必要がないならRunspacePoolでできるんじゃね >>786
おお、あるのか来週会社で使ってみる
ありがとう function target
・入力を読み続ける
・最後に読んだ入力を1秒間隔で出力し続ける
・入力が q なら終了
処理遅延を無視した理想的な使用例が
. { $s = Get-Date; 1; sleep 3; 2; sleep 3; 'q' } | target | % { '{0} {1}' -f (Get-Date) - $s, $_ }
0:00:00.0000000 1
0:00:01.0000000 1
0:00:02.0000000 1
0:00:03.0000000 2
0:00:04.0000000 2
0:00:05.0000000 2
となるような function target はどうすれば実現できますか
処理時間でずれていくのはもちろんかまいませんが
入力待ちにも出力を続ける具体例が知りたいです おっと間違い
(Get-Date) - $s でなく ((Get-Date) - $s) だ >>792
「qなら終了」が何を示すかによるが、powershellのパイプは途中で打ち切る事は原則できないと考えた方が良い。
(endブロックが呼ばれない不完全なハックならググれば見つかる)
またパイプ処理の待機はpowershellのメインスレッドの待機という意味になるので、
そこに非同期イベントを介入させたい場合はそのイベント用の別スレッドを走らせておく必要がある。 (New-Object -ComObject Shell.Application).NameSpace(10).MoveHere(ファイルパス)
上記の方法でファイルをごみ箱に移動する場合ファイルが1個なら問題ないんですが、
ファイルパスをを"z:\*"みたいにワイルドカードで指定するとなぜか
ごみ箱でなくC:\Users\ユーザー名にファイルが送られてしまいます。
どうすればごみ箱に送れましょうか? >>794
q は出力スレッドの停止マークで、入力の最後も意味するつもりだった (その後の入力はない)
という考えをくみ取って欲しくて例を付けたのだが伝わらなくて残念
パイプラインの中断にSelect-Object -First 1する話は知ってる
ていうか本題から話をそらそうとしてません?
知りたいのはメインスレッド以外からプライマリパイプラインに出力する方法
パイプラインの次段に送るにはどうすればいいか具体例が欲しい シェルスクリプトやPowerShell が遅いのは、
毎行、何かのプロセスを起動するからじゃないの?
多くはプロセスの起動時間だろう
Ruby は、外部プロセスを起動しなければ、プロセスは1つのまま。
並行処理もあるけど
grep は、1GB を1秒! >>796
そもそもパイプは同期的にしか動かないので、次段でいくら細工しても上流が出力を起こしたタイミングに縛られる。
話を単純にするなら不規則な出力を受ける処理と一定間隔で出力する処理は分けるべきだろうね。 >>795
移動なら、robocopy のmov/move を使えば? >>799
どうやればごみ箱に移動できましょうか? >>795
シェル名前空間はバグだか仕様だか判らない所があるから真面目に考えても無駄
もうそういう仕様と考えてファイルは1個1個送れば?
ワイルドカードはgciで展開できるんだし >>798
サブスレッドがパイプラインに書き込めば次段が動くんじゃないの?
言い換えると >>792 のfunction targetは実現不可能ということ? >>801
どうもありがとうございます。そうします。 最近この言語で書くことあるけど関数の呼び出しを最初に書かないとエラー起こすなんて知らなくて問題解決に時間がかかった
多分ほとんどの人が関数はメインの後に書きたいと思うんだけどファイル分けて呼び出したりしてるの? >>804
> 多分ほとんどの人が関数はメインの後に書きたいと思うんだけど
んなことはない
呼び出される方を前に書かなきゃいけないのは他の言語でも多いぞ >>805
定義を上書きできる言語なら呼び出し順序に意味があると思うけど、そうじゃないならただの手抜き仕様 >>806
実行速度が速くなる、スコープが明確になる、などのメリットがあって敢えて採用されてるんだよ
JSとかも古くからあるfunction構文は順序関係ないが今推奨されてるアロー関数だと前に書かなきゃだめだ あとスパゲティを防ぐ効果があるというメリットもあるな
C言語だとそれを目的にプロトタイプを書かない人もいる 関数同士の依存関係が明確で前の関数が後の関数に依存しないなら初めてのコードを読みやすくなるというメリットもあるな Java隆盛くらいの時代には関数はどこに書いても良いのが当たり前として定着したけど
関数型プログラミングでは関数宣言は変数や定数の宣言と同じようなものだからどうしても順序を意識せざるを得ない
順序の扱いを自動でやってくれる仕組みがホイスティングなんだけど、そのルールの分かりにくさやいやらしさが開発者に嫌われてJavaScriptのvarがletとconstに取って代わられた歴史がある >>804
メインの部分をメイン関数として書いて実行時にメイン関数を呼び出すようにすればよいのでは?PowerShellはシェルとしても動くので実行時に先に関数が定義されていないといけないのは自然な動作のような気もする。 >>812
begin process endブロック使いたいときに発狂しそうだな powershellでもclass内なら順序関係なくなるよ 自分のコード見たら別に後から宣言してても実行できてるんだが
コマンドレットの定義だとホイスティングされるとかある? >>816
古臭いと言われても、前に書いた方が無駄な混乱をさけられる。 動的言語は第一級関数のクロージャが多いから、
関数外で宣言したローカル変数が、関数内へ持ち込まれるので、
スコープが広くて、ヤバイ
さらに、JS はホイスティングされるから、超ヤバイ
ただし、Ruby の関数だけは第一級関数のクロージャではなく、
関数外で宣言したローカル変数は、関数内へ持ち込まれない
だから他の言語よりも、圧倒的にバグらないので、初心者向き get-childitem select-object Full name,でownerを追加する方法はありますか?ご存知の方、ご教示願います。 >820
Get-ChildItemだけではowner情報は取れない、Get-Aclで情報取得する必要がある
組み合わせで良ければ以下の様にSelect-Objectでプロパティ追加すれば出来る
Get-ChildItem|Select-Object FullName,@{n="Owner";e={Get-Acl $_.fullname|% {$_.Owner}}} Outlook を起動してメールを送りたいのですが
本文のメールのフォントサイズや色の指定が一切無視されます。
Outlook 側の設定なのか、コードが悪いのかもよくわからず。。。
スレ違いならすいません
===================
$outlook = New-Object -comObject Outlook.Application
$mail = $outlook.CreateItem(0)
$mail.Subject = "件名テスト"
$mail.HTMLBody = "<html><head><style type='text/css'>
body {font-size:11; font-family:Meiryo UI;}
</style></head><body>
ああああ<span style='text-decoration:underline; text-decoration-color:red;'>いいいい</span>ううう<br>
</body></html>"
$inspector = $mail.GetInspector
$inspector.Display()
#$mail.Send()
===================
上記のコードだとメイリオは設定されますが、フォントサイズは8.5になるし下線は黒色になります。
なにとぞご教示お願いします font-sizeの値に単位が無いから無視されてんじゃね >>823
試したはず・・・と思いつつも確認したら普通に変更されました!!!
11px で確認したのかもしれません。11pt と書いたら普通に反映されました
ありがとうございます
ただ下線は相変わらず赤色にならず、黒色のままです。
#FF0000 も試したけど変わらず・・・
どうやら text-decoration-color がそもそも使えないようでした。
さささ<span style='text-decoration:underline; color:red;'>ししし</span>すすす<br>
とやったら文字も赤くなりましたが下線も赤くなりました。
Outlook に使える html の仕様との戦いな気がしてきた
これはどこで尋ねたら・・・ 後はstyle属性をシングルクォーテーションで括ってるのが気になった
全体の括りをシングルにして属性値をダブルに変更で動くと思うよ シングルとダブルは変わりませんでした…
実際はPowerShellでメール本文内に変数を当てこむので
シングルのままでいこうと思います
あと下線だけ赤色は私の勘違いでした
赤下線の時は文字も赤くして問題なかったのでとりあえず解決しました
お手数おかけしました
ご助言くださった方ありがとうございました 二週間ほど前に自分で調べて書いたのに、どうやって書いて動かしたのか全く思い出せなくて困ってます
自分で自分が信じられないんですが、教えてください。
やりたいこと:Read-Hostで指定したフォルダに存在するフォルダを取得し、各フォルダに指定したファイルをコピーする
引っかかっている点:
1)$input = Read-Host "コピー先フォルダを指定"
たとえばここでcopyと入力。規定のフォルダがC:\作業とする。
入力の結果、c:\作業\copyとして、ここにあるサブフォルダを取得したいので
$inputをc:\作業\copyにしたい。
2)Get-ChildItem でディレクトリ名のみ取得するには?
それでforeachでやってたと思うんですが・・・。 Get-ChildItem -LiteralPath ([IO.Path]::Combine("C:\作業", (Read-Host "コピー先フォルダを指定"))) -Directory -Name >>828
わー初見のコード
でもおかげでなんとかできました。ありがとう。 多分いままで書いてたコードはこれ
# 規定のフォルダのパスを作成
$parent = join-path 'c:\作業' $input
# 上記パスのサブフォルダ作成
$names = ls -pspath $parent -di | % name
下記はエイリアス(関数の別名)
ls := get-childitem
% := foreach-object # 上記パスのサブフォルダ作成
↓
# 上記パスのサブフォルダ名を取得 >>821
遅くなりました。
set-location -pathで場所を指定したら、指定したフォルダのownerを取得できました。ありがとうございます。
get-Childitem -recruse -file ┃select-Object directoryName ,name ,extension ,Length Creationtime, lastACCESStime ,lastwriteTime, fullname ┃Export‐csv ‐Encodeing default xxx.csv
と一緒にできなかったのが悔やまれます。 >>821の何がだめで、あるいは何が分からなくて、そのコマンドに組み込めなかったのか分からんな。
起点ディレクトリ自体の情報もCSVに含めたい、って事なのかな。 powershellの学習曲線は険しい
本人が納得したならもうそれでいいだろう ならこんな感じで。
$dirPath = "起点ディレクトリのフルパス"
[IO.FileInfo]::new($dirPath) | %{$_; $_ | Get-ChildItem -Recurse -File} | Select-Object DirectoryName, Name, Extension, Length, CreationTime, LastAccessTime, LastWriteTime, FullName, @{N="Owner";E={($_ | Get-Acl).Owner};} | Export-Csv -Encoding Default xxx.csv
CSVの出力先がフルパスなら、Set-Locationはいらない。 >>837
ありがとうございますm(_ _)m
とりあえずownerを取得できました。列の入れ替えはPowerQueryで対処します。
neme,Extensio,owner,...したかったのですが。 Pythonでやったら楽なのに…と思う処理も他のメンバーに配る可能性を考えると泣く泣くpowershellでやることになる
嫌いな言語ではないけど凝った処理を書こうとすると見た目の癖が強いソースコードになりがち 質問なのですがパイプラインの結果を関数に渡して先頭からk番目を取り出すには一体どうすればorz
やりたいことはパイプラインの結果を検証する処理をサブルーチン化したい(k番目を取り出すのはその第一歩)
とりあえず書いたがうまく行ってないやつ:
function Test-RegEnt($reg_query_result, $exp_type, $exp_value) {
$reg_query_result | Select-Object -Index 2
}
Write-Output ("Test_A1:" + ($result | Select-Object -Index 2)) # 2行目が意図通りselectされる(" RegisteredOwner REG_SZ Admin")
$result2 = Test-RegEnt($result, 'REG_SZ', 'Admin')
Write-Output ("Test_A2:" + $result2) # A1と同じ結果になるかと思いきや、'Admin' になる 先頭3行抜かしましたorz
$result = reg query 'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion' /v 'RegisteredOwner'
$cnt = 0
$result | ForEach-Object{ "TEST[$cnt}:" + $_; $cnt++ }
この次に>>842のコード。 んまーなんかこれだとうまく行ったけんども思ってたのと違う……
function Test-RegEnt($exp_type, $exp_value) {
$Input | Select-Object -Index 2
}
$result = reg query 'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion' /v 'RegisteredOwner'
$cnt = 0
$result | ForEach-Object{ "TEST[$cnt}:" + $_; $cnt++ }
Write-Output ("Test_A1:" + ($result | Select-Object -Index 2))
$result2 = ($result | Test-RegEnt('REG_SZ', 'Admin')) # パイプラインの結果を引数ではなくパイプで渡す
Write-Output ("Test_A2:" + $result2)
実はパイプラインの結果(オブジェクトの配列)は関数引数に渡せなかったりするので?
つなみにfunctionの引数部分で [array]$reg_query_result としてみてもうまく行かなかった。 文法が違う。
Test-RegEnt -reg_query_result $result -exp_type 'REG_SZ' -exp_value 'Admin'
とか
Test-RegEnt $result 'REG_SZ' 'Admin'
とか。
または
function Test-RegEnt {
Param (
[Parameter(ValueFromPipeline=$true)]
[string] $reg_query_result,
[string] $exp_type,
[string] $exp_value
)
Begin {
$cnt = 0
}
Process {
$cnt++
$idx = $cnt - 1
if ($idx -eq 2) {
$reg_query_result
return
}
}
}
$result | Test-RegEnt -exp_type 'REG_SZ' -exp_value 'Admin' >>845
レス㌧クス
$Input利用(>>844)とBegin { } Process { }利用の違いはわかりた
$resultが数億オブジェクトだったりしたら後者の方がパイプラインがスムーズに流れてよさげ(未検証
一方、
>実はパイプラインの結果(オブジェクトの配列)は関数引数に渡せなかったりするので?(>>844)
については関数の呼び出し箇所が
$result | Test-RegEnt -exp_type 'REG_SZ' -exp_value 'Admin' # (1) OK
Test-RegEnt -reg_query_result $result -exp_type 'REG_SZ' -exp_value 'Admin' # (2) NG (エラー)
やったから、これは「パイプラインの結果は関数引数には渡せない」((1)のように書くしかない)ということでFA? Select-ObjectのSkipとFirst使えばできるのでは? >>842
> $result2 = Test-RegEnt($result, 'REG_SZ', 'Admin')
$result2 = Test-RegEnt $result 'REG_SZ' 'Admin'
でやりたいことはできるのではないでしょうか パイプラインと引数のどちらでも動くようにしたいなら
function Test-RegEnt {
Param (
[Parameter(ValueFromPipeline=$true)]
[string[]] $reg_query_result,
[string] $exp_type,
[string] $exp_value
)
Begin {
$cnt = 0
}
Process {
foreach ($item in $reg_query_result) {
$cnt++
$idx = $cnt - 1
if ($idx -eq 2) {
$item
break
}
}
}
}
あくまでシンプルめのサンプルなんでSelect-Object -Index 2と全く同じ挙動とか期待しないように。
※作りこむならパイプが繋がってるのかチェックして分岐の処理書いたりする。
なお、大量のデータをパイプラインに流すのはお勧めできない。
パイプラインは途中での打ち切りとか難しいし、
結局は普通にループ処理書いた方が速いし制御しやすいし分かりやすい事が多い気がする。 レス㌧クス、しかしながら大量データを引数で関数に渡すのはメモリ消費量、応答速度ともに悪くなることがわかったからやめるわサーセン;;;
どういうことかというと、bigfile.txtが(1行何か書いたいた後 Ctrl+A Ctrl+V Ctrl+V を22回反復とかで作った)
4194305行の巨大なテキストファイルだったとして、
function Test-FileContent([string[]] $lines) { $cnt = 0; foreach ($line in $lines) { $cnt++; Write-Host "cnt=" $cnt } }
$lines = Get-Content .\bigfile.txt # (1)
Test-FileContent($lines) # Get-Content完了後の結果を引数で渡す
とするとお、「cnt= 1」が表示される前に(1)で永劫の時間待たされるますが、
function Test-FileContent() { $cnt = 0; foreach ($line in $Input) { $cnt++; Write-Host "cnt=" $cnt } }
Get-Content .\bigfile.txt | Test-FileContent # Get-Contentが読んだら即パイプで渡す
とすると*即座に*「cnt= 1」以降のカウントが始まる つなみに
>$resultが数億オブジェクトだったりしたら後者の方がパイプラインがスムーズに流れてよさげ(>>846)
も検証すた、
>>846のレスポンスが即時のコードと似通っているが関数内でBEGIN { } PROCESS { }でなく$Inputをforeachループで回した場合、
すわなち
function Test-FileContent() { $cnt = 0; foreach ($line in $Input) { $cnt++; Write-Host "cnt=" $cnt } }
Get-Content .\bigfile.txt | Test-FileContent
とすると、、「cnt= 1」が表示される前に永劫の時間待たされる、、、
というわけで、パイプライン(の後段まで)に大量のデータを無駄に流すなというのは真やが
生じてしまった大量のデータはむしろパイプラインにしか流さないのが正義…… >>851の肝心のところに誤記が合ったスマンヌorz
*即座に*「cnt= 1」以降のカウントが始まるコードは正しくはこれ↓
function Test-FileContent() { BEGIN { $cnt = 0 } PROCESS { $cnt++; Write-Host "cnt=" $cnt } }
Get-Content .\bigfile.txt | Test-FileContent パイプの利点は個数を意識しなくて済むことだけど中断が一切できないしデメリットの方が多い
よっぽどの事情でもない限りコマンドレット自作しても遅いだけで良い事なんて1つもない
公式のselect -firstなんかはパイプの流儀に従ってないから似た事をしようとしてもあれ?って自らの間違いに気付くんだよ
powershellの深遠を覗くとそのいい加減さにガッカリするだけ メモリなんて遅さで相殺される
powershell + 大量データ = 遅くて不採用 >>857
パイプに希望を見てるのかな
その認識では近く失望させられるだろう 一番良いのは、Windowsを使わない
これにかぎる
こんなクソなOSを世界中から捨てるべき Windowsは汎用事務処理端末としては競合なしだ メモリ効率とスループットは交換できるようなものではない
手軽さが不要ならPythonでも使っておけばいい いまだにPowerShellがWindows専用だと思ってるアホを真っ先に捨てるべき で>>842の質問に戻るのですだが、動かなかったのは単純だが根本的な誤解してたのが原因……
C/C++と同じだろうというつもりで
>$result2 = Test-RegEnt($result, 'REG_SZ', 'Admin')
という呼び出し方に書いたが、これだと「Test-RegEntの第一引数$reg_query_resultに「配列」@($result, 'REG_SZ', 'Admin')を渡す」という意味になる
ので、関数内で
>$reg_query_result | Select-Object -Index 2
とやったら当然そのindex=2の要素 'Admin' が関数の出力となってた、というしくみ 正しくは>>845式に
>Test-RegEnt -reg_query_result $result -exp_type 'REG_SZ' -exp_value 'Admin'
またはその省略表記としては
>Test-RegEnt $result 'REG_SZ' 'Admin' # カンマ区切りではなくてスペース区切り
にせねばならなかった
ことがわかったorz
止むにやまれない事情で昨日一日で1500行書いてデバッグしたらその過程でわかった|||。n_ あと他のスクリプトをincludeするときの欠き方が気づかないとわかりにくい……
util.ps1 を同じフォルダにある someapp.ps1 からインクルードする場合は
'.\util.ps1'
ではダメで、
.'.\util.ps1'
にしないとutil.ps1で定義した何物も呼び出せないorz
ここで先頭の「.」はutil.ps1のスクリプトスコープを呼び出し元のスコープと同じにするという意味やがちょう紛らわしい…… あと関数内においては代入文、[void]にキャストした文、if文とかの条件式 を除く全ての文が出力を持つ、
という仕様のせいで危うく恐ろしいバグを作り込むところやった;;;
function Show-ErrDlg($msg) {
$wsobj = new-object -comobject wscript.shell
$wsobj.popup($msg, 0, 'エラー', 0 -bor 16)
}
function Test-Equipment1() {
$result = (何かのテスト)
if (!$result) { Show-ErrDlg('何かのテスト failed.') }
return $result
}
でとするとテストが失敗したときも if (!(Test-Equipment1) { exit 1 }
(テスト正常終了の表示処理)
でテスト正常終了の表示が出るorz
これは何でかというと$wsobj.popup($msg, 0, 'エラー', 0 -bor 16) 」がクリックされたボタンの番号を出力する結果、$resultがまたしても配列
@( (「なんかのテスト」の結果), ($wsobj.popup()でクリックされたボタンの番号) )
となりこれが Test-Equipment1() の戻り値となり、それをif文で評価したら最後の要素 (OKボタンのコード6)と評価されるため、!6なので常に偽になるというしくみ、、、、
こう修正すたら直った
function Show-ErrDlg($msg) {
$wsobj = new-object -comobject wscript.shell
[void] $wsobj.popup($msg, 0, 'エラー', 0 -bor 16) # [void]付ける
}
わかるかこんなもん……
および原理的にlint的な機械的チェックもできない…… これはデフォルトで出力無しとして、
なんかの接頭辞を付けた文だけが結果がパイプに出力されるるようにする仕様であるべきだった希ガス
(出力が無いというミスはすぐ気づける
てかWrite-Outputを省略可能としているのがそもその誤り……
※ 個人の感想です
いっぱい連投したがTeamsのつもりでShift+Enterしたら投稿されてしまったせいやスマンヌorz
いじょ ============================
function Hoge([int]$num) {
echo "Debug"
return ($num + 1)
}
$a = Hoge(1)
echo $a
============================
こうすると $a には Debug と 2 の2つが入る
============================
function Hoge([int]$num) {
.{
echo "Debug"
} | Out-Null
return ($num + 1)
}
$a = Hoge(1)
echo $a
============================
こうすると $a には 2 の1つしか入らない
不要なところは 「 .{ ~~~ } | Out-Null 」で表示を抑制したら楽になるかも >>842に言える事はパイプで何番目とかいう考えは捨てた方がいい
パイプは途中で処理を打ち切る機能が欠落してるから何番目だけに用があろうが全ストリームを読み終わるまで終わらない ほぼ誤差だが |Out-Null より $null= で処理した方がパフォーマンスがよく、可読性も高い >>871
わかりた
パイプラインの打ち切りは、実現方法はあるが円満な解決方法はなさげ(どれもこれもなんかしらのミソがつく
パイプで$n番目、というだけならSelect-Objectしたらv3以降ならn+1番目以降を打ち切ってくれる
$n = 2
Get-Content .\bigfile.txt | Select-Object -Index $n | Foreach-Object { Write-Output "cnt=${n}: $_" } # bigfile.txtが1億行あっても瞬時に戻って来る
が、これは「Select-Object -Index ~」部分を関数化したら元の木阿弥になる
function Select-Nth($n) { $Input | Select-Object -Index $n | Foreach-Object { Write-Output "cnt=${n}: $_" } }
Get-Content .\bigfile.txt | Select-Nth(2) # bigfile.txtを1億行全部読み込んでからおもむろに出力する
構文的に$_を使った関数やフィルタとしては書けない
データを見て条件が成立したら打ち切り、というのになるともっとマンドクセ……
https://winscript.jp/powershell/308 >>870
それな!
ワカル
㌧クス、
>>872
わかりた
function Hoge([int]$num) {
[void].{
echo "Debug"
}
return ($num + 1)
}
$a = Hoge(1)
echo $a
でも逝けた 関数の出力が意図せず(うっかり)複数個所から行われ分かりにくい点は
バッチとかシェルスクリプトの挙動に合わせすぎた為だろうね。
例えばping.exeを対象2か所に実行するバッチ(.bat)をパイプで繋げたら、
バッチ1つの実行で、ping2回の20行程度がパイプに流れる。
PowerShellスクリプトや関数もこれと同じだと考えればそんな違和感ないはずなんだけど、
元々他の言語なんかで「関数の戻り値は1つ(明示的な1つor関数末尾の1つ)」とか
「明示的に変数格納や出力などしなければ、メソッドや関数の戻り値は捨てられる」
って事に慣れてるし、PowerShellも同じ文法だから同じ挙動を期待しちゃう。
上でも出てるけど、標準ではパイプに流さない仕様とした方が
敬遠される点が減ったと思う。 パイプはスレ違いのバッチスレでドヤ顔ワンライナーするぐらいしか能が無いと言っても過言 1GiB程度のファイルを処理するときにはパイプは重宝するよ バッチファイルのパイプはメカニズムが違う
あれは実質一時ファイルを作って次段に渡しているだけなので遅い、と言おうと思ったが
"*<CR><LF>" を2^23個書き並べたbigfile.txtに対してコマンドプロンプトで
type bigfile.txt | find /C "*"
とやったら「瞬時に」
4194304
と返って来るのに、PowerShellで
Get-Content .\bigfile.txt | find.exe /C "*"
とやったら永劫の時間待たされた後
FIND: パラメーターの書式が違います
と言われた後Ctrl+Cにも応答しなくなた……どうなってるのこれ…… そりゃパイプで外部コマンドに送ったら1行ずつfind.exe実行して終了するだろうから
おかしなことにもなるだろうよ > あれは実質一時ファイルを作って次段に渡しているだけなので遅い
それはシングルタスクだったDOS時代の話だろ
NTのcmd.exeには当てはまらない cmd.exeはパイプやfor /Fのコマンドとかワーカースレッドを生成して
別タスク(子環境)としてデータの送り手や受け手を作ってるかな Get-WinEventでSystem.evtxだかのファイルを処理させるとコマンドレットが終了しても一定時間プロセスがファイル掴みっぱなしになるのどうにかしてくれ
わざわざ別プロセスでGet-WinEvent用のpowershell起動させる間抜けなコードになったぞ 処理速度都合なのかな〜って思ってるけど閉じる手段は提供して欲しい。
自分は.NETのクラス使って処理書いちゃった。 エクスプローラでファイル選択してコピーして
(Get-ClipBoard -Format FileDropList).GetType().ToString()
→ System.Collections.Generic.List`1[System.Management.Automation.PSObject]
うん。
Get-ClipBoard -Format FileDropList | %{$_.GetType().ToString()}
→ System.Collections.Generic.List`1[System.Management.Automation.PSObject]
うn?
foreach( $info in Get-ClipBoard -Format FileDropList ){ $info.GetType().ToString() }
→ System.Collections.Generic.List`1[System.Management.Automation.PSObject]
えぇ…
Get-ClipBoard -Format FileDropList | %{$_} | %{$_.GetType().ToString()}
→ System.IO.FileInfo
…
[System.IO.FileInfo[]](Get-ClipBoard -Format FileDropList) | %{$_.GetType().ToString()}
→ System.IO.FileInfo
うーん…
$list = Get-ClipBoard -Format FileDropList
$list | %{$_.GetType().ToString()}
→ System.IO.FileInfo
まぁ…
なんか不必要に使いづらい気がするのは自分だけかな。 $(Get-ClipBoard -Format FileDropList) | %{$_.GetType().ToString()}
→ System.IO.FileInfo
バッドノウハウの領域だなー 隠し属性が設定されたファイルが排他されてるとかで読めない状況のときに
-ForceついたGet-Contentで読もうとすると隠し属性解除されるのは理由あるんだろうか 質問で申し訳ない
AccessでエクスポートしたxlsxをPowershellでComObjectを作成してOpenしたいんだけど
破損している云々で発行元を信用しますか?ってダイアログのせいでOpen出来ない
https://learn.microsoft.com/ja-jp/office/vba/api/excel.workbooks.open
ここによると15個目の引数で1を指定(xlRepairFile)すれば良さそうなんだけど
Powershellで実行するとOpenプロパティが無いよって怒られる。
実際のコードはこう
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $True
$fileName = (Get-ChildItem "test.xlsx").FullName
$book = $excel.Workbooks.Open($fileName, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, [System.Type]::Missing, 1) とりあえずこうすると回避できた。
using namespace Microsoft.Office.Interop.Excel
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $True
$fileName = (Get-ChildItem "test.xlsx").FullName
$param = @([Type]::Missing) * 15
$param[0] = $fileName
$param[14] = [XlCorruptLoad]::xlRepairFile
$workbooks = $excel.Workbooks
$book = $workbooks.Open.Invoke($param) $param = @([Type]::Missing) * 15
は
$param = @([Type]::Missing) * 0xFF
のほうが人にやさしい気がする >>892の後者は配列に255を掛けてるように見えるのだが
人にやさしい部分てどこ? マスクしてるのかと思ったわ
ちゃんとソース見てなかった
すまんこ PowershellのGUI使って簡単な時報を作りたい。
System.Windows.Forms.Timerを使って作ったんだが今何時判定で$Aの数字が毎回リセットされるんでIntervalの回数だけ別ウィンドウが開きまくる。
使い方間違ってるか?教えてくれさい。
$timerTestTick {
【適当に現在時表示】
if(【指定した時間になったら】-and【$Aがtrueなら】){
start-prosess 【音楽ファイルを別ウィンドウで再生して処理継続】
$A = false
}
}
$timerTest.Add_Tick($timerTestTick)
$timerTest.Interval = 200
$timerTest.Enabled = $TRUE
$timerTest.Start()
【適当にフォーム作って表示】 >$Aの数字が毎回リセットされるんで
それ$Aを更新しようとする度に毎回スクリプトブロックで別の$Aが生成されるからやね
([ref]$A).Value = $false
と書けば元の$Aを探しにいくから更新できると思う
Powershellのはまりポイントの1つやね powershellでGUIって、c#使えない宗教的理由でもあるの? >>898
スクリプトブロックていうのが働いてるのか。とりあえず試してみるありがとう。
>>899
宗教的理由というより書けないから出来ることで色々やってみてた。
というかPowerShell単体でC#つかえるの? PowerShellでGUI作れるんか!
知らんかった これは興味ある GUI作れるとかマジか
ワザワザHTMLソース内部に仕込んでWEBベースでやりとりしてた俺は一体・・・ 一応.NET言語の1つではあるからGUIは普通に作れるが
俺はC#コード埋め込んでFuncやAction経由で必要時にpowershellと連携する感じの使い方だな
Powershellのコードだけで作るの自体が割と面倒なのや型チェックが働かない辺りとかかあんまメリットを感じない htaの代わりとしてforms呼び出して組んでたけどcssが便利すぎて最近は使ってないな...
wpfはどうなんだろうか... 日付を元に指定範囲内の一意の数字を出すってできる?
200ぐらいある今日の一言的なものを毎日ランダムで出したいんだがアプリケーションを再起動すると変数リセットされて別の単語出てしまうのを抑止したい。 その日の初回の結果をファイルに出力して
2回目以降はそのファイルを読み込みに行けば良いのでは >>908
それしかないかなぁ
ファイル出力を避けたかったんだが >>908
できそうだからファイル出力の方向でやってみるありがとう。 >>908
できそうだからファイル出力の方向でやってみるありがとう。 その条件なら日付をシード値とみなせるんだから
別の単語が出てくる方がおかしいんじゃないのか
基礎的な論理思考力が欠けているね あ、-SetSeedって完全固定の疑似乱数なのか。
再起動したら変わると思ってた。 Get-Random -SetSeed $(Get-Date -Format "yyyymmdd") -Maximum 200 >>914
seedなんてもんがあったのか!
ありがとう! 912 と 913 をワンライナーで視覚化しただけやぞ >>905
wpfも普通にいけるけど、vsのデザイナーがないと厳しいから、じゃあc#でいいかとなりがち
htaの代替としたらwpfかwinformで枠だけ作ってwebview2埋め込むのがおすすめ
qiitaでも記事があったはず webview2ランタイム自体の埋め込み手段がなあ こんにちは
フォルダの配下のすべてのテキストファイルを結合した文字列を出力したいです
フォルダ直下のファイルだけなら
Get-Content *.txt
でできました
該当するファイルの一覧は
Get-ChildItem -Recurse -Filter "*.txt" -Name
でできましたが
Get-ChildItem -Recurse -Filter "*.txt" -Name | Get-Content
としてもエラーになります PSNativeCommandPreserveBytePipe が楽しみすぎる PSNativeCommandPreserveBytePipe が楽しみすぎる この言語って3次元以上の配列って出来ないって認識であってる?
二次元は
$array[0,0]で良いんだよね?
三次元というかジャグ配列?はとりあえず使えるから
$array[0][0,0]
でやってるんだけど中の2,3次元目とか中の要素数カウントが出来なくて結構困ってる ジャグ配列で良いんだったら$array[0][0][0]…といくらでも入れ子にすれば良かろうに 多次元配列はこうじゃない?
$array = [Object[,,]]::new(4,5,6) # 3次元、4×5×6
$array[0,0,0] = "(0, 0, 0)"
$array[0,0,1] = "(0, 0, 1)"
# 参照は「$arraya[0,0,0]」だと配列スライスと間違えそうだから「$array.Get(0,0,0)」の方が安全かも。 要素数は
$array.GetLength(0) # 4
$array.GetLength(1) # 5
$array.GetLength(2) # 6 あぁそっか普通に出来るのか初期化の仕方が悪かったみたい
普通の初期化でも3次元出来るんだね
調べたらジャグ配列のが処理早いそうなので結局そっち採用すると思う
レスしてくれた方有難う PowerShell Community Call - October 19 2023
https://github.com/PowerShell/PowerShell-RFC/blob/master/CommunityCall/notes/20231019_Notes.md
Ideally a GA Nov, may have 7.5 preview in December, not guaranteed Ideally に進んで今月中の GA に期待
ところで [console]::OutputEncoding って shift_jis と utf-8 のどっちにしてます? 7入れて何かいい事あんの?
それ、OS標準の5.1でできますよね?
もしかして、デベロッパーのオナニーに付き合わされていませんか? powershellでデフォルトの環境に手を加えないとできないことは他のPG言語に任せるべきだと思う Windows PowerShell 5.1 と PowerShell 7.x の相違点
ttps://learn.microsoft.com/ja-jp/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.3
入れる入れないは個人の自由
5と7は共存できるし別にデメリットないから7入れてるよ スクリプト言語としてならどっちでもいいけど
インタラクティブなコマンドラインシェルとしてなら7が圧倒的に便利
sjis出力コマンドとutf-8出力コマンドの混在環境なら7.4でさらに便利 >>935
シェルとしてどんな点が改善されているのですか? 半角英数のファイルにUTF-16を追加する事故が起きないのは助かる aに1代入したいんですがどうすればいいですか?
function hoge(){
[int]$a;
function moge(){
$this.a = 1;
}
moge;
return $a;
}
hoge # ・classのメソッドとして書く(何か知らんがレキシカルスコープになる)
・javascriptを使う Get-Variable とか >>475,898 とか $script:a とか。
なお「[int]$a」では宣言できてない。 ref[]はpowerahellにおいてCポインタ程度には重要知識なのに
界隈で然程語られる事もなく知られていない
知られてはいけないとでも言うのだろうか… >>940
とあるオブジェクトの初期設定にこんな感じで書いてたんですが無理そうですか
了解しました
class hoge:object{
[object]$o_a;
[object]$o_b;
hoge (){
[int] $cnt;
function object_a_init(){
$this.cnt = 1;
}
object_a_init;
}
} 親スコープにある変数の値を変えたいなら
Set-Variable -Name a -Value 1 -Scope 1 >>944
>>941をよく読んだ方がいいよ
昔の俺のレスの引用だけどね
変数の型指定は値で初期化する必要があるよ 横からすいません
なんでこれはエラーになるんでしょうか
pwsh -nop -c "[System.Text.Encoding]::GetEncoding(932)"
-c を使わずに pwsh -nop と起動して
[System.Text.Encoding]::GetEncoding(932)
を入れると動くのもわからない・・・ MethodInvocationException: Exception calling "GetEncoding" with "1" argument(s): "No data is available for encoding 932. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method."
だそうです Encoding.RegisterProvider でぐぐったら解決しました >>939を動くように直したげたよ
function hoge(){
[int]$a = "1" # $aを値で初期化しつつ型を強制。型宣言というよりキャストに相当。[int]に強制されるので値が文字列でも$aにはSystem.Int32に変換された値が入る
$a.GetType() | Write-Host # $aの値の型をコンソールに出力 System.Int32
function moge(){
([ref]$a).Value = 1 # >>941-942の言うブロックで変数を生成せず既存の変数を参照して値を代入する記法
}
moge
$a # 関数の打ち切りの意図を除きreturnキーワード不要。powershellのfuncitonは最後に限らず値を返す式は全部返そうとする
}
hoge >>939
参照渡しでやってみれば?
--------
function hoge
{
[int] $a = 1234
function moge
{
param (
[ref] $b
)
$b.Value = 5678
}
moge -b ([ref] $a)
return $a
}
hoge
--------
about_Ref
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-7.3 リンク先読んでないけど、.exeにパイプしたときに早くなる(普通になる)のかな 文字列を8文字ごとに分割して配列に格納したいのですが
文字列が8文字以下だと1文字ずつ分割されてしまいます。
$nums = @()
$nums = $num -split '(.{1,8})' | Where-Object{$_}
上記を実行すると、
$num = 12345678 のとき、$num[0] は 1が格納されるのですが、
12345678が格納されるようにするには、どうすればよいでしょうか。 >>955
すみません。誤字です。
誤: $num[0] は 1が格納されるのですが、
正: $nums[0] は 1が格納されるのですが、 $numsには文字列の"12345678"が代入されてるから
$nums[0]だと"12345678"の1文字目の1が返る
1行目を [string[]]$nums = @() とするか
2行目を $nums = @(12345678 -split '(.{1,8})' | Where-Object{$_}) とすればOK >>0957
ありがとうございます!
できました。 PowerShell 7.4 だと
PS> python -c 'print("\\")'
\
と期待通りになるけど Windows PowerShell 5.1 だと
PS> python -c 'print("\\")'
File "<string>", line 1
print(\)
^
SyntaxError: unexpected character after line continuation character
となるのは何が起きてるの?
7.4 でも $PSNativeCommandArgumentPassing を Legacy にすると同じみたいだけど
具体的にどうなってるのか今更だけど知っておきたい 対処法が知りたいんじゃなくてどう解析されたかが知りたい コマンドラインのパース内容をデバッグできるコマンドレットがあって
inactionで紹介されてた気がするけど何か思い出せない $PSVersionTable
PSVersion 5.1
Ruby の1-liner では、%Q 記法があるから大丈夫
ruby -e 'print %Q(\\)'
\
ruby -e 'print %Q(あaい)'
あaい >>962
Get-Command | sls "breakpoint|callstack"
デバッガーについて - PowerShell | Microsoft Learn
ttps://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_debuggers?view=powershell-5.1 >>964
回答ありがとう、でも思い出せないのは>>959の流れからの「コマンドラインのパース」自体の事だったんだ。
in Action引っ張り出して確認したが↓の事で、これで違いが分かるかも。(v7.4で確認してない。)
Trace-Command -Option All NativeCommandParameterBinder -PSHost {python -c 'print("\\")'} 他に、形態素解析みたいに分解・解析できる機能もあった気がするが忘れた PowerShell 7.4 だと python -c 'print("\\")' ですむことを
Windows PowerShell 5.1 だとどう書けばいいんだ
--% を使っても使わなくても分からん パラメータの干渉受けたくないなら普通にStart-Processでいいでしょ 対話シェルでStart-Processするのはつらい つらいのは我慢するとしてStart-Processを使ってどう書けばいいの pythonの引用符はシングルもダブルもエスケープシーケンス展開されるからおかしな解釈になってるだけだな
pythonの仕様を呪うがいい pythonは例として使っただけだしどうでもいいよ
あくまで興味の対象はPowerShellのコマンドラインのパース
やっぱ 7.4 すげぇで終わってもいいんだけど
なんか 7.4 の --% が腐ってる気がする
5.1 の想定通りの --% と違って勝手に引用符加えてぶっ壊してる感じ
はやいとこ直して欲しい いやわかんないなら別にいいけど一応書いとくわ
もちろん 7.4 を Windows で使う話
stop-parsing token (--%) は以後のパースをしないはずなのに
引用符無視して空白で引数を分割してコマンド起動してるっぽい
CreateProcessまでに引用符が変に補完されるから意図通り動かない
--% が出てきたら引数の分割はネイティブコマンドに任せないとあかん
$PSNativeCommandArgumentPassing が Legacy の時と同じ処理な
そういうわけで Legacy 扱いされる .cmd とかでは問題ない
おかしいのは Standard 扱いされる .exe なんかの場合だけ
PSNativeCommandArgumentPassing の説明
>この実験的な機能が有効になっていると、PowerShell は、ネイティブの実行可能
>ファイルを呼び出すときに、文字列を再構築する現在の機構ではなく、
>StartProcessInfo オブジェクトの ArgumentList プロパティを使用します。
にある、文字列を再構築するのが Legacy、Argumentlist を使うのが Standard
という違いがわかれば理解できる話なんだが期待はしてない Powershellを体系的に学ぶにあたっておすすめの本ってありますか?
やりたいことをググってコードをコピペして使用してる状態で、コードの理解度が深まらないと思ったので体系的に学びたいと思いました。
自分のPowershellの用途は、日常的な作業の自動化(テキストファイルの読み書き、ファイルの起動やタスキル、アクティブウィンドウの切り替え、robocopyでのバックアップなど)で使っています。 Windows PowerShell in Action Third Editionは読んだかね
https://sd.blackball.lv/library/Windows_PowerShell_in_Action_3rd_Edition_(2017).pdf
ただしこの本は6年前の情報。英語PDFだけど今は色々と翻訳手段もあるから読めると思う
powershellならWindows上の事であれば大抵の事はできるけど
本当に便利に使うならC#や.NETの前提知識があった方がいいだろうね
C#関連で可能な事ならほぼpowershellに置き換え可能だから Powershell で複雑なものは書けないから結局、Ruby になる。
WSL2, Linux側からなら、Windows側をいじれるし rubyガイジなんだろうけどそこでrubyになるのは贔屓目に見てもおかしいだろ >>975
コードをコピーしてchatGPTかPerplexityで「PowerShellで"〜〜〜"はどういう意味?」を聞けばいい >>975
「PowerShell実践ガイドブック」は、PowerShellの動作の仕組みが詳しく解説されていてよかった
謎に思える挙動についても説明がある
ちょっと古いが(5年半前に出版) microsoft learn じゃダメなの?
ttps://learn.microsoft.com/ja-jp/powershell/scripting/how-to-use-docs?view=powershell-7.4
ttps://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about?view=powershell-7.4 975です。おすすめのドキュメント教えてくれた方ありがとうございます。
一つ気になったのですが、学習の順番としてはC#もしくは.NETから入ったほうが効率的ですか?
自分がPowershell始めたきっかけがグローバルホットキーをうまく使いたいというのが始まりで、
後述URLのコードをベースに継ぎ足しで書き加えている状態です。
PowerShellとC#でグローバルホットキーを登録する
https://qiita.com/minr/items/72b02d673727f9eb4c37
※自分のC#のレベルはHelloWorld出したぐらいまで、.NETについても知識としてほぼ白紙です。 ダボゥクリッコゥで実行出来ない面倒臭いものを誰が使うんですか? ダブルクリックで実行できたWSHはLOVELETTERワームやら何やらでセキュリティが低いとみなされて非推奨になりましたとさ
めでたしめでたし 例えば、デスクトップにショートカットを作って、リンク先を以下のようにすると、
ダブルクリックでPowershell を起動して、Ruby でスクリプトを実行する
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe "ruby C:/Users/Owner/Documents/Ruby/a.rb"
初心者はRuby で始めるべき。
C# はRubyの10倍、時間が掛かるし難しい 同じ民族同士、分断せずに仲良くしろよ
DevBlogs - Microsoft Developer Blogs
ttps://devblogs.microsoft.com/ MatzはWindowsやC++に興味無いから
よほどエゴサでもしないかぎり気の毒なことにはならないわ
知らぬが仏 というか、Windowsの日本語localizationのデフォルトが未だにクゾだから、
「☑ベータ: ワールドワイド言語サポートを Unicode UTF-8 を使用」
を最初から標準にしていないかぎり、Windowsを日本語で使うこと自体、クソということになる 外部コマンドを実行するときに外部コマンド自体は正常な戻り値を返してるのにpowershellで動かすとNativeCommandErrorって例外が出るんだけどなんでだかわかる人おる? ISE上で実行した場合に標準エラー出力があると
戻り値に関係なくNativeCommandErrorになるけど、このこと?
そうでなければ>>996にプラスしてバージョンなどの環境も示してね。
あと次スレ
https://mevius.5ch.net/test/read.cgi/tech/1701241669/ このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 654日 0時間 45分 29秒 5ちゃんねるの運営はUPLIFT会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《UPLIFT会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
4 USD/mon. から匿名でご購入いただけます。
▼ UPLIFT会員登録はこちら ▼
https://uplift.5ch.net/
▼ UPLIFTログインはこちら ▼
https://uplift.5ch.net/login レス数が1000を超えています。これ以上書き込みはできません。