20/04/29 11:22:32 HjIuTJYT.net
Powershellに逆参照演算子なんてないでしょ
ドットはMember access operatorとDot sourcing operatorの二種類のはず
ほかの言語との混同があるのでは
C言語の & と * を参照演算子、逆参照演算子と訳すなら分かるし、-> を逆参照演算子と呼ぶのもまあ分かる
201:デフォルトの名無しさん
20/04/29 12:43:39.55 YtBfjahw.net
日本語版Windows PowerShell in Actionにそう書いてあった気がするんだが、
確かにMSDN見るとMember access operatorだ
202:デフォルトの名無しさん
20/04/29 12:50:10 YtBfjahw.net
vscode上だと高度な関数のbeginブロックで定義した変数が、
processブロック中で使ってるにも関わらず未参照の警告が出るんだけど良い解決方法ないでしょうか
未参照確認自体は便利なので黙らせたくはないです
203:デフォルトの名無しさん
20/04/29 21:28:33 kj6lHAl7.net
>>199
逆参照と訳す人が現実にいるんだから仕方がない
URLリンク(www.google.com)
204:デフォルトの名無しさん
20/04/30 09:42:14 Lei4veWw.net
>>200-201
古い about_Operators には property dereferences operator とあるので、改名されたのかも。
URLリンク(docs.microsoft.com)
205:デフォルトの名無しさん
20/04/30 14:51:17 qeUJHkfv.net
URLリンク(docs.microsoft.com)(v=wps.640)
. プロパティ逆参照演算子
オブジェクトのプロパティとメソッドにアクセスします。
$myProcess.peakWorkingSet
(get-process PowerShell).kill()
206:デフォルトの名無しさん
20/05/01 00:27:41 iyqswZZm.net
一般的には
参照 アドレスを取り出す
逆参照 アドレスに入っている値を取り出す
だけど値を取り出すことを「逆」と訳した経緯がわからん
207:デフォルトの名無しさん
20/05/01 05:46:31 XmUvZ7vC.net
変な翻訳だな
値参照でいい
208:デフォルトの名無しさん
20/05/01 12:57:54 578ddPng.net
dereferenceはやっぱ参照外しかな
referenceってポインタ(または名前)が主語で、実体に向かって矢印が向いている、ポイントしている状態
逆参照というとこの矢印を逆に辿る、変数からポインタを探すになっちゃう
接頭辞de-を「離れる」と理解せずに、かなり派生的な「逆」と訳して定着した誤訳に近い語だと思う
209:デフォルトの名無しさん
20/05/01 12:58:58 578ddPng.net
いずれにしてもPowershellでdereferenceなんて概念を持ち込む必要がないからメンバアクセス演算子って名前に改善されたんでしょう
210:デフォルトの名無しさん
20/05/01 16:33:54 5CcYXcTT.net
C系は逆参照じゃないの
むしろ参照外しのほうがわからんかったが
211:デフォルトの名無しさん
20/05/01 17:34:48.85 578ddPng.net
どっちがデファクトスタンダードかって話とどっちが正しいかって話は別だから
確信犯とか姑息みたいに誤用の方が普及して定義が揺らいでる言葉はいろいろあるけどどう使うかは話者次第
212:デフォルトの名無しさん
20/05/04 01:09:24.67 hArtKUaR.net
初心者です
move-item等でファイル名に[]があるとエラーがある事を知りました
ようやく -LiteralPath つければ良いと分かりましたが、
デフォルトの仕様がワイルドカード受け付けるのって初心者殺しというか…
なれてる人はこっちの方が便利なんでしょうか
213:デフォルトの名無しさん
20/05/04 03:59:19.96 eeiLu4M/.net
Powershell好きだけどファイル名の [ ] の扱いは失策だと思う
214:デフォルトの名無しさん
20/05/04 08:21:59.04 ayLem+RW.net
?や*すらファイル名に使えるUNIXの世界へようこそ!
215:デフォルトの名無しさん
20/05/04 09:28:04 hArtKUaR.net
>>213
やっぱりそうですよね・・・
比較演算子も、-matchで[ ]があるとエラーになって困りました
これもいろいろ調べてようやく-match [regex]::escape() にすれば良いと分かりましたが・・・
PowerShellって参考書もあまりなくて古いし、ネットの情報もあまりなくてなかなか学習が進みません・・・
そもそもPowerShell ISEのヘルプで -pathは「ワイルドカード文字を許可する false」って嘘書いてあるのが・・・
216:デフォルトの名無しさん
20/05/04 11:59:27 dnvbBZmT.net
ファイル名はともかくmatch が正規表現で比較ってのは割と知られているような気もするけど
217:デフォルトの名無しさん
20/05/04 13:19:22.94 XmeTIU4M.net
対になるlike演算子があるからなんとなくわかる
ところでreplaceの正規表現じゃない版が欲しい・・・
218:デフォルトの名無しさん
20/05/04 13:22:34 eeiLu4M/.net
たしかに-matchの話に限っては単なる勘違いだな
match(一致)と言われて部分一致だと思うかといえば、普通はpattern matchでしょう
参考にしたサイトが悪かったのかもしれない
正規表現を使わないなら "a[b]c".Contains("[b]") でいい
219:デフォルトの名無しさん
20/05/04 13:25:02.05 eeiLu4M/.net
>>217
上のレスで気付いたかもしれないけど
"a[b]c".Replace("[b]", "[d]") で置換できるよ
220:デフォルトの名無しさん
20/05/04 13:42:36.44 XmeTIU4M.net
なるほどね
そういや -replace [regex]::escape()でもOKか
221:デフォルトの名無しさん
20/05/04 16:06:32 hArtKUaR.net
>>216 >>218
教えていただいてありがとうございます。
自分がやりたかったのは、例えば hoge[hoge] というファイル名で拡張子の違う
複数のファイルの移動だったんですが、最初は
$hoge = "hoge[hoge]"
Move-Item "C:\test\$hoge.*" "C:\test2"
これは失敗しました([ ]があるファイルを処理していて気がつきました)
いろいろ調べて
Get-ChildItem "C:\test\*.*"|Where-Object{$_.basename -match [regex]::escape("$hoge")}|Move-Item -Destination "C:\test2"
してみて成功しました
今回教えてもらって
Get-ChildItem "C:\test\*.*"|Where-Object{$_.basename.contains("$hoge")}|Move-Item -Destination "C:\test2"
これでOKみたいです。まだ冗長な気もしますが・・・
222:デフォルトの名無しさん
20/05/04 17:06:49.01 LlR+aKwZ.net
パスの角括弧の扱いはpsの一番いけてないとこだからね
角括弧のみをエスケープする場合は次のようにする
move "C:\test\$hoge.*".Replace('[', '``[') "C:\test2"
もしくは-Filterパラメータが角括弧をワイルドカード扱いしないことを利用して
move "C:\test\*" "C:\test2" -Filter "$hoge.*"
223:デフォルトの名無しさん
20/05/04 18:54:18.78 hArtKUaR.net
>>222
なるほど。 [ だけエスケープすれば大丈夫なんですね
ようやく引っかかってた所から脱出できそうです
皆さん大変ありがとうございました
224:デフォルトの名無しさん
20/05/06 21:11:41.78 prm5gj7H.net
これってクラス多めのオブジェクト指向でやるべきなのか、
高度な関数多めのパイプライン志向(?)でやるべきなのか、
どっちがいいのかな
225:デフォルトの名無しさん
20/05/07 01:36:33.14 k5uIH00p.net
オブジェクト使い回す設計のほうが読みやすそうならそうする
高度な関数ってどんなんやねん
226:デフォルトの名無しさん
20/05/07 02:22:01 GVyLSOna.net
高度な関数ってずいぶん懐かしい単語だな、普通に関数でいいと思うよ
全ては無理に和訳しようとしたMSが悪い
227:デフォルトの名無しさん
20/05/07 08:07:17 O8jL8wQb.net
>>224
本来のシェル的な使い方がメインなら
関数でパイプライン多用した方が使いやすい
普通のアプリに近いものを作る場合には
クラスでOOPした方が使いやすい
228:デフォルトの名無しさん
20/05/07 08:26:30 H2g0PsUL.net
PSのクラスって判らんからコード量増えたらC#埋め込むわ
229:843
20/05/07 09:38:19 1Drf/TcZ.net
PSのクラスって機能が足りないとかはあるけど特に難しい所はないと思うが…
230:デフォルトの名無しさん
20/05/07 23:47:47 cnY/r+Lf.net
教えてください。
WindowsServer2012のADユーザー情報の取得についてです。
testunyo.local
┗ユーザー
┗Users
上記OUにあるユーザーの情報のうち、
ログオンID
フルネーム(表示名)
所属するグループ名 の情報をcsvで抽出したいとき、
Get-ADPrincipalGroupMembership -identity test | Select-Object name | Format-Wide -Column 20 | Out-String -Width 500 >> C:\work\logtest.csv
とすると所属するグループ名しか抽出できません。
A列にログオンID、
B列にフルネーム、
C列以降に所属するグループ名
と、1ユーザー1レコードで表示させたいとき、
どのようにするのが良いでしょうか?
Get-ADPrincipalGroupMembershipではなく、csvdeを使うのが良さそう
とは思ったのですが、うまく抽出できませんでした。
231:デフォルトの名無しさん
20/05/08 01:23:43 GBARQ9Uf.net
Select-Object name で name プロパティしか抽出できてないとか?
232:デフォルトの名無しさん
20/05/08 12:22:27 Fn4yfVbS.net
>>221
Ruby で作った。
DryRun なので、実際には実行されません
require 'fileutils'
dest_dir = "C:/test2"
keyword = "hoge[hoge]"
# 絶対パスのディレクトリ名の後ろに、* を付けること!
# . で始まる、隠し directory, file を除く
glob_pattern = "C:/test/*"
src_dir = File.dirname( glob_pattern ) # ディレクトリパスだけを取り出す
Dir.glob( glob_pattern )
.select { |full_path| File.file?( full_path ) } # ファイルのみ
.select { |full_path| File.basename( full_path, ".*" ) === keyword } # 拡張子を取り除いた部分のファイル名
.each do |full_path|
dest_path = dest_dir + "/" + File.basename( full_path ) # ファイル名
FileUtils::DryRun.move( full_path, dest_path )
end
出力
mv C:/test/hoge[hoge].txt C:/test2/hoge[hoge].txt
233:デフォルトの名無しさん
20/05/08 13:46:42 fxtS7XW6.net
GetNewClosureで作ったクロージャからトップレベルに定義した関数にアクセスできんのだがスコープどうなってんだ?
function Hoge () {}
{ Hoge }.Invoke() #うごく
{ Hoge }.GetNewClosure().Invoke() #うごかん
234:デフォルトの名無しさん
20/05/08 15:09:04 eZ8FT/L5.net
またキチガイが湧いてきたか
NG しやすいように、コテハン付けて欲しいわ
235:デフォルトの名無しさん
20/05/10 09:05:34.07 oQrk4XHl.net
>>233
トップレベルと呼んでいるのは、(仮に) Hoge.ps1 の Script スコープでいいよね?
PowerShell のクロージャは、動的モジュールにバインドされたスクリプトブロック。
モジュールの Script スコープは、常に Global スコープの直接の子なので、
クロージャの Local スコープは、Hoge.ps1 の Script スコープの子孫にならない。
スコープの親子関係:
[Global] - [Script(Hoge.ps1)] <== Hoge 関数の定義されているスコープ
[Global] - [Script(動的モジュール)] - [Local] <== 問題のクロージャ内のスコープ
236:デフォルトの名無しさん
20/05/10 15:23:52 JjPR8mXC.net
Ruby で作った!
237:デフォルトの名無しさん
20/05/11 21:37:49 41JmE2xy.net
>>235
なるほど
PowerShellって便利で面白いけど時々変な癖あるよな
238:デフォルトの名無しさん
20/05/12 21:11:03 2xTEfvW8.net
Closures in PowerShell
URLリンク(devblogs.microsoft.com)
Windows PowerShell uses dynamic modules to create dynamic closures.
A closure in computer science terms (at least as defined in Wikipedia) is “a function that is evaluated in an environment containing one or more bound variables.”
A bound variable is, for our purposes, a variable that exists and has a value. The environment in our case is the dynamic module.
239:デフォルトの名無しさん
20/05/15 09:02:37.24 B71gCNON.net
v6.2.5
URLリンク(github.com)
v7.0.1
URLリンク(github.com)
240:デフォルトの名無しさん
20/05/15 09:54:10 JVqn6ak1.net
昔ながらのPowerShellとPowerShell Coreって共存できんの?
PowerShell CoreってクロスプラットフォームだけどWindowsの管理コマンドとか旧PowerShell資産とかとどれぐらい互換性あるのかな
241:デフォルトの名無しさん
20/05/15 12:11:51 spGK6l8f.net
>>240
共存できる。Core をインストールしても、PowerShell 5.1 を置き換えない。
インストールされるパスが違うし、そもそも実行ファイルのファイル名も違うので。
242:デフォルトの名無しさん
20/05/15 21:26:49 OwQtRj4C.net
Windows PowerShell 5.1 から PowerShell 7 への移行
URLリンク(docs.microsoft.com)
243:デフォルトの名無しさん
20/05/16 02:28:51 LVL/9uGV.net
むしろCore版を上書きしてほしんだが
Powershellで検索すると大量に出てきてうざいし、
Win+Xのショートカットから起動したいし
244:デフォルトの名無しさん
20/05/16 02:29:08 LVL/9uGV.net
逆、Core版で、ね
245:デフォルトの名無しさん
20/05/16 21:17:04 I3dvVBqE.net
>>243
タスクバーにピン留めでは駄目なの?
246:デフォルトの名無しさん
20/05/19 11:55:42.51 1h+Pwucu.net
C#クラスFooをAdd-Typeして
Fooを継承するpowershell class Barを定義しようとするとVSCodeの静的解析に型Fooが無いって言われる
実行時には問題なく動作するんだけど鬱陶しい
どうにかならんのかこれ
247:デフォルトの名無しさん
20/05/19 16:52:18 JYrNQD+Z.net
>>246
現状では継承クラスを別ファイルにして読み込み元で先にadd-typeしてから遅延読み込みするしかない
core系統ではusing assemblyの実装が保留されてるから
将来的にはおそらくそこをクリアしたusing assemblyが実装されると思うけど
>実行時には問題なく動作するんだけど
それはどこかしらで自分で先にadd-typeしてるからだと思う。そうじゃないとエラーで止まる
今の段階で最善と思われる方法はマニフェストモジュールにして
psd1内でRequiredAssembliesに継承元のアセンブリを設定すること
それをusing moduleで読み込むようにすれば最も自然に使える
248:デフォルトの名無しさん
20/05/19 20:59:56 JYrNQD+Z.net
>>246
ごめんよく読んだら的外れなレスだったわ
C#のコードをadd-typeするってことね
.NETのクラスを継承すると勘違いした
249:デフォルトの名無しさん
20/05/19 21:17:33 qw+UaCoQ.net
Suppressing Rules
URLリンク(github.com)
250:デフォルトの名無しさん
20/05/19 21:19:20 qw+UaCoQ.net
urlおかしかったからやり直し
URLリンク(github.com)
251:デフォルトの名無しさん
20/05/25 18:56:03 1KC3re4i.net
教えてください。Windows10です。
クリップボードに次の文字をコピーします。
Get-ChildItem -Path "c:\doc★"
これをPowershellに貼り付けると、勝手に★が削除されて
Get-ChildItem -Path "c:\doc"
になってしまいます。正常に貼り付けるには、
どのようにすればよろしいでしょうか?
252:デフォルトの名無しさん
20/05/25 20:12:08 zwsFaYDZ.net
Powershellコンソールのバグらしいよ
253:デフォルトの名無しさん
20/05/26 00:18:53 oj/EjNC2.net
そうですか。バグなのですか。ありがとうございました。
254:デフォルトの名無しさん
20/05/26 08:41:22.73 Ay3ltgvo.net
コンソールじゃなくてPSReadLineのバグでしょ
Remove-Module PSReadLine を実行した後なら普通に貼り付けできる
255:デフォルトの名無しさん
20/05/26 08:45:00.47 TWTiQG7J.net
>>251
知らんかった、こんなバグが有ったのか。ウチの環境でも再現した。
echo '★★★★'
echo '☆☆☆☆'
これを貼り付けると、
echo ''
echo ''
こうなったわ。
256:デフォルトの名無しさん
20/05/26 08:56:54.86 lYnWhySi.net
>>254
ホントだ、治った
257:デフォルトの名無しさん
20/05/26 10:38:39.59 DUXfe990.net
なん…だと…
258:デフォルトの名無しさん
20/05/26 11:36:52.76 fIo6Jhad.net
スクリプトならok?
259:デフォルトの名無しさん
20/05/26 15:52:47 q+hnim2U.net
スクリプトならOKだよ
画面を色分けする処理がバグってたはず
260:デフォルトの名無しさん
20/05/26 19:42:26 wDroaLCo.net
echo 'yatta-man★ko-hi-★raita-'
いやー、もう少しで社会的に抹殺されるところだったよ
261:デフォルトの名無しさん
20/05/27 18:03:22.45 8S2S1tlw.net
htmlのdiffでまともな方法ない?
262:デフォルトの名無しさん
20/05/28 16:49:06.82 NkjBuM4x.net
Get-ADPrincipalGroupMembership -identity testuser1 | Select-Object name | ・・・
というshellを2つ続けて流すと、ログファイルに記載されたとき、
1つ目のshellの結果と2つ目のshellの結果に3行の空白が生まれます。
なぜでしょうか・・・?
263:デフォルトの名無しさん
20/05/29 08:40:18 GJdaxgw0.net
>>262
shell ってどういう意味ですか?
264:デフォルトの名無しさん
20/05/29 09:24:43 AL+gVKfO.net
URLリンク(ejje.weblio.jp)
shellとは
貝殻、(カキの)殻、(カメ・エビ・カニなどの)甲羅、(カブトムシなどの)硬い外皮、(鳥の卵の)殻、(果実・種子などの)殻、(豆類の)さや、(建物・乗り物などの)骨組み、外郭、船体
265:デフォルトの名無しさん
20/05/29 09:26:47 d1uEOplb.net
>>263
すみません。
PowerShellスクリプト、です。
266:デフォルトの名無しさん
20/05/29 12:54:04.01 1C1s9P85.net
ログファイルはフィルターして見るから、どうでも良くね?
サーバー運用部門しか見ないし。
一般社員が見ないだろ
数年保存して捨てるだけの、ログファイルの書式にこだわっても、仕方ない
267:デフォルトの名無しさん
20/05/29 14:16:17.31 8xO19nFy.net
なぜそうなるかを知りたいってことだろ
>>262がどういうスクリプトを流してるのかさっぱり要領を得ないから原因は全くわからんけど
268:デフォルトの名無しさん
20/05/29 15:24:58.90 GJdaxgw0.net
>>265
(1)1回目と2回目は、パラメータが違うのですか?それとも、全く同じ内容で実行のタイミングが違うだけですか?
(2)何度も尋ねるのは煩雑なので、可能であれば端折らずに記述内容を全て記載してもらえませんか?
269:デフォルトの名無しさん
20/05/29 15:38:08.24 QVnkNeSg.net
まあでも、センスは出るよね
270:デフォルトの名無しさん
20/05/29 15:53:45 d1uEOplb.net
>>266
正にその通りなんですが、サーバー運用部門としてみる人数が多いので、
可能な限り整った書式で出力したい次第です。
>>267
今までも様々なログを出力してきましたが、
今回のような不思議な現象は初めてで、どうしてなのか解明したいです。
>>268
(1)1回目と2回目はほぼ同じスクリプトです。
(2)端折っていない実行したスクリプトを記載します。
>>269
センス、出ますよね・・・。
端折っていないスクリプトです。
以下二つを、同時に流しました。
Get-ADPrincipalGroupMembership -identity test111 | Select-Object name | Format-Wide -Column 20 | Out-String -Width 1000 >> C:\work\logtest0528.csv
Get-ADPrincipalGroupMembership -identity test222 | Select-Object name | Format-Wide -Column 20 | Out-String -Width 1000 >> C:\work\logtest0528.csv
よろしくお願いします。
271:デフォルトの名無しさん
20/05/29 16:13:12.46 1C1s9P85.net
たぶん、1つ目のアプリが、3行の改行コードを出力してるからだろ
例えば、HTML みたいに、データ内の区切りに、CR・LF の改行コードを使っているものもある。
それらを出力すると、空行ができる
それか、アプリにバグがあって、
正しくデータが取れず、空行だけが出力されているとか
272:デフォルトの名無しさん
20/05/29 16:16:40 yQdVc2qs.net
>>262 > というshellを2つ続けて流すと
>>270 > 以下二つを、同時に流しました。
相手を混乱させて遊んでるっていう理解でいい?
273:デフォルトの名無しさん
20/05/29 16:45:48.92 d1uEOplb.net
>>271
バグですか・・・
必要なデータは取得できているんですが、
その下に不必要な空行が発生するのは、もう、仕方ないんですかね・・・
>>272
混乱させるつもりはなかったのですが、
>>270のスクリプトは、エクセルで作成をしました。
(A1に1つ目のスクリプト、A2に2つ目のスクリプト・・・という感じです)
作成したスクリプトの全てをコピーし、PowerShellに貼り付ける、
という作業をしました。
274:デフォルトの名無しさん
20/05/29 16:56:48 xfksWnzq.net
そもそも Get-ADPrincipalGroupMembership が何個の要素をパイプラインに流してるか見てみたら?
275:デフォルトの名無しさん
20/05/29 17:01:45 GJdaxgw0.net
>>270
ユーザが所属しているグループをファイルに吐きたいわけですよね。
1ユーザごとに1ファイル、グループは横に並べて出力、という条件は必須ですか?
276:デフォルトの名無しさん
20/05/29 17:11:08 GJdaxgw0.net
>>273
力技だけど、これでどうですかね。うちの環境ではうまく行ってます。
(Get-ADPrincipalGroupMembership -identity testuser111 ).name | %{"$_`t"| Out-File -NoNewline -Encoding ascii -Append -FilePath "C:\a.txt"}
277:デフォルトの名無しさん
20/05/29 17:38:52 d1uEOplb.net
>>274
その考えは無かったです・・・
調べてみます。
>>275
>>270のコードでtest111,test222としているところ、
実際には3000程の数があります。
実行するスクリプトの結果(ログ)は一つのファイルに追記する形で、
理想の出力は、
1ユーザーの所属するグループが、1セル1グループに横並びになることです。
A B C
1 グループ1 グループ2 グループ3 ←1つ目のスクリプトで流したtest111の所属するグループ
2 グループ1 グループ3 グループ4 ←2つ目のスクリプトで流したtest222の所属するグループ
というイメージです。
>>276
ありがとうございます!
検証してみます。
278:デフォルトの名無しさん
20/05/29 18:01:42 d1uEOplb.net
>>276
-NoNewline でエラーになります・・・
Out-FileのパラメーターとしてNoNewLineというものが無いと表示されます。
276さんはうまくいったとのことなので、
環境が違うのでしょうか・・・?
279:デフォルトの名無しさん
20/05/29 18:11:11 GJdaxgw0.net
>>278
じゃあ、最初の趣旨とは違ってますけどこれでどうでしょう。
"C:\users.txt"には、対象となるユーザ名を1行に一つという形式で記述してください。
まあ、対象ユーザも Get-ADObject で取得したほうがスマートですけどね。「特定のコンテナ内のユーザ」といった条件なら簡単なのですが。
$users = Get-Content "C:\users.txt"
foreach ($user in $users) {
if($user -eq ''){
break
}
echo $user
$grps = (Get-ADPrincipalGroupMembership -identity $user ).name
$line = ''
foreach ($grp in $grps){
$line += '"{0}",' -f $grp
}
echo $line
Out-File -InputObject $line -Encoding utf8 -Append -FilePath "C:\grp.csv"
}
280:デフォルトの名無しさん
20/05/29 18:22:56 d1uEOplb.net
>>279
ありがとうございます。
すでに私に理解できる範囲を超えているのですが、、、
データを取得したい対象ユーザーは”特定のコンテナ内”です。
その場合であれば、どこを変更するようになるでしょうか?
すみません。ご教示ください。
281:デフォルトの名無しさん
20/05/29 18:44:52.24 GJdaxgw0.net
>>280
じゃあこれが良いと思います。
3行目の「"OU=Newusers,DC=example,DC=local"」となっている箇所を、実際の環境に置き換えてください。
以下は、ドメイン名が「example.local」、最上階層の「Newusers」という OU 内の UserObject を全て取得する場合の例です。
デスクトップ上に 'yyyyMMdd_hhmmss.csv' を出力します。1カラム目はユーザ名で、2カラム目以降がグループ名です。
$Now = Get-Date -Format 'yyyyMMdd_hhmmss'
$logPath = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ('{0}.csv' -f $Now )
$users = Get-ADUser -Filter * -SearchBase "OU=Newusers,DC=example,DC=local"
foreach ($user in $users) {
if($user -eq ''){
break
}
Write-Host ('{0} : ' -f $user.SamAccountName) -NoNewline
$grps = (Get-ADPrincipalGroupMembership -identity $user).name
$line = '"{0}",' -f $user.SamAccountName
foreach ($grp in $grps){
$line += '"{0}",' -f $grp
}
echo $line
Out-File -InputObject $line -Encoding 'utf8' -Append -FilePath $logPath
}
282:デフォルトの名無しさん
20/05/29 18:48:35.39 GJdaxgw0.net
>>280
追伸。まず、
Get-ADUser -Filter * -SearchBase "OU=Newusers,DC=example,DC=local"
だけ実行して希望通りのユーザオブジェクトが出力されることを確認してください。
"OU=Newusers,DC=example,DC=local"の記述方法がキモになりますが、
よくわからない場合は「distinguished name」でググってください。
283:デフォルトの名無しさん
20/05/29 23:38:38 d1uEOplb.net
>>281
>>282
本当にありがとうございます!
今は検証環境に繋げないので、明日、試してみます!
また結果を明日の夜します!
284:デフォルトの名無しさん
20/05/30 00:38:50 AsxV9jzU.net
ふーむcsvde使った方が楽そうだな
285:デフォルトの名無しさん
20/05/30 07:47:46.25 Z2NT1d95.net
PowerShellを使って結果出す事それ自体が目的になってしまう事はよくある
286:デフォルトの名無しさん
20/05/30 08:49:02.75 d859mrLa.net
結果を出すことが目的なのはいいだろw
PowerShellを使うことが目的になると言いたいんだろうけど
287:デフォルトの名無しさん
20/05/30 10:31:28 KjUAf8QQ.net
>>284
このスレでそれを言うのは、料理レシピサイトで「ファミレスで食うほうが楽じゃね?」って言うのと同じ
288:デフォルトの名無しさん
20/05/30 13:24:05 9sn/rA++.net
余計なソフトのインストールを禁止している会社って
PowerShellでプログラミングするのは認められているの?
289:デフォルトの名無しさん
20/05/30 16:10:14.39 KjUAf8QQ.net
>>288
会社によるだろう、としか
290:デフォルトの名無しさん
20/05/30 23:54:06.76 iu9cBMrA.net
合法とも禁止とも明示してる企業は見たことないな
はっきり禁止されてないなら使ってOKって解釈で今まで問題になったことはない
291:デフォルトの名無しさん
20/05/31 00:40:12 +AbQWtDJ.net
ちなみにレジストリをいじるのは認められているの?
292:デフォルトの名無しさん
20/05/31 01:57:51 81hmFEht.net
うちは、総務部の担当者に許可を求めることになっているが、
その担当者がよく解らない人のようで、ダメと言われたことはないな。
293:デフォルトの名無しさん
20/05/31 12:20:40 b/Zu62PW.net
管理者権限アカウントの申請は必要てのはあるよね
294:デフォルトの名無しさん
20/05/31 17:04:24.67 rtfQfZlf.net
部のPC担当じゃなければせいぜいパワーユーザーだと思うけど
295:デフォルトの名無しさん
20/05/31 23:56:26.74 iB7Renkw.net
>>281
報告が遅くなりました・・・。
検証環境で実行した結果、
A列にログオンID、B列に所属するグループ1、が表示されました。
ここまではかなりいい感じだったのですが、
所属するグループの2つ目以降が出力できませんでした・・・。
2つ目以降を出力できるよう考えてみましたが、
取ってつけた知識では太刀打ちできませんでした。
すみません。2つ目以降を出す方法を教えていただけますでしょうか。
csvdeも考えたのですが、
先に形になったのがGet-ADPrincipalGroupMembershipだったので、
そちらを主軸に考えていました。
理想形が出力されればcsvdeでも全く問題ありません!
レジストリはいじれますが、あくまでもシステム管理部であるから、
という感じですね。
あー、PowerShellを使うこと、が目的になってしまってる感はありました。
理想の出力結果が出れば、フリーのツールでもOKなんですが、、、
296:デフォルトの名無しさん
20/06/01 00:21:41 vdF2NbM2.net
余分な空白さえ消えればいいなら
Out-String -Stream | ?{$_ -ne ""} | %{$_.trim()}
297:281
20/06/01 08:58:32.48 Pn8bHbMj.net
>>295
説明がしにくいので、pastebin に貼りました。
URLリンク(pastebin.com)
こちらで試している限り、所属グループが複数でも正しく出力されています。
現象的に、12行目の
$line += '"{0}",' -f $grp
が、「+」が抜けて
$line = '"{0}",' -f $grp
になっているように思えます。
確認1:
コードはコピペされてますか?それとも、画面を見ながら手打ちで転記でしょうか。
もし後者の場合はコピペで試してみてください。
また、仮にコピペだったとしても、5ちゃんからではなく上記 URL の pastebin からコピペしなおしてみてもらえますか。
確認2:
ファイルに書き出すものと同じ内容を画面にも出力するようにしています。
グループ名が一つだけ、というのは画面上でもでしょうか?
298:デフォルトの名無しさん
20/06/01 20:38:24 6WpvIjeC.net
>>296
ありがとうございます。
>>270に記載のスクリプトを編集して、
Get-ADPrincipalGroupMembership -identity test111 | Select-Object name | Format-Wide -Column 20 | Out-String -Stream | ?{$_ -ne ""} | %{$_.trim()} >> C:\work\logtest0528.csv
という感じになるでしょうか?
>>297
ありがとうございます。
確認1:5ちゃんをコピペしてました。
明日検証環境を使えるので、URLのpastebinからやってみます。
確認2: グループ名が一つだけ、というのは画面上でもそうなってます。
(実際には所属するグループが3つあるユーザーを作りテストしています)
「+」は確かに抜けているところがありますね・・・。
修正して、もう一度検証してみます。
ありがとうございます!
299:デフォルトの名無しさん
20/06/01 23:33:53 5NIHbXOS.net
「慶應卒の学歴なんていらない」10代起業で成功する子の共通点
URLリンク(www.excite.co.jp)
起業で成功するキャリア形成の仕方とは? 元プロサッカー選手で起業家の鈴木啓祐氏に聞いた
URLリンク(sogyotecho.jp)
【アプリ開発で起業】必要な心得とマネタイズ方法のすべて
URLリンク(www.dreamgate.gr.jp)
学生起業家が開発、「人を軸に本を探すアプリ」とは?読書通じて「考える力」養って
URLリンク(newswitch.jp)
島田商高生がアプリ考案、発表 ICT起業家育成プログラム
URLリンク(www.at-s.com)
医師コンビが「治療用アプリ」で起業、禁煙に続き高血圧治療アプリを開発
URLリンク(diamond.jp)
好きが高じて“カレー起業”、キャッシュレス決済アプリ「TOKYO MIX CURRY」の挑戦
URLリンク(diamond.jp)
300:デフォルトの名無しさん
20/06/02 12:00:25.43 TaVu0Z+0.net
>>297
pastebinに記載いただいたスクリプトをマルっとコピペで、
理想形として出力することができました!!
本当にありがとうございました!!
一文で作成しようと考えていましたが、
こんなに長いスクリプトが必要とは思いませんでした・・・。
301:297
20/06/02 13:51:33.65 4gU+uBDd.net
>>300
うまく動いたようで良かったです。
あのスクリプトですが、1行ごとに見ていけば実行してることは単純です。
また、記述する際も省略表記はなるべく避けるようにしましたので、
ググって意味を調べるのも容易かと思います。
Windows 系インフラの構築/運用では PowerShell を活かせる場面が
多くありますので、この機会に覚えておくと強力なスキルになると思います。
302:デフォルトの名無しさん
20/06/02 16:16:22.57 e5f6kXC+.net
csvdeは全部エクスポートしておけば適当なスクリプトでどこでも試せるけど
PSはいちいちAD鯖に繋ぎに行く形だからテストが大変なんよね
303:デフォルトの名無しさん
20/06/02 18:35:36 TaVu0Z+0.net
>>301
本当にありがとうございました。
次にこの出力したデータを加工して、今度はインポートする作業が待っていますが、
調べて頑張ってみます。
>>302
はい。家庭で検証ができないのでテストが大変でした。
csvdeも今後使うことがありそうですので、注意してみておきます。
304:300
20/06/03 17:19:22.25 OSlS0ZCr.net
すみません。頑張り切れませんでした。
>>297 の出力結果に加え、
そのアカウントの有効/無効の情報を同時に取得したいと思い、
Enabledを加えてみましたが、うまく出力できませんでした。
Enabledは、Write-Hostの前に入れればよいと思いましたが、合っていますか?
305:300
20/06/03 18:10:05 OSlS0ZCr.net
Write-Hostの前じゃなかったです。
後ろでした。
これで
$Now = Get-Date -Format 'yyyyMMdd_hhmmss'
$logPath = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ('{0}.csv' -f $Now )
$users = Get-ADUser -Filter * -SearchBase " OU=ユーザー,DC=test,DC=local "
foreach ($user in $users) {
if($user -eq ''){
break
}
Write-Host ('{0} : ' -f $user.SamAccountName) -NoNewline
Write-Host ('{0} : ' -f $user.Enabled) -NoNewline ←★★ココ
$grps = (Get-ADPrincipalGroupMembership -identity $user).name
$line = '"{0}",' -f $user.SamAccountName
foreach ($grp in $grps){
$line += '"{0}",' -f $grp
}
echo $line
Out-File -InputObject $line -Encoding 'utf8' -Append -FilePath $logPath
}
これで画面には出るようになりました。
出力するファイルにも出るようにするには、、、
306:297
20/06/04 11:06:18 TeZKrupD.net
>>305
$line = '"{0}",' -f $user.SamAccountName
の下に、
$line += '"{0}",' -f $user.Enabled
を追加してみてください。
あと、
if($user -eq ''){
break
}
は、対象のユーザ名をファイルから読み取っていたバージョン (>>279) の名残ですので、バッサリ削除しても良いですね。
まとめるとこうです。
URLリンク(pastebin.com)
念のため解説しておくと、$line は、最終的にファイルに書き込むことになる文字列を格納しています。
で、代入時に「=」ではなく「+=」を使ってますので、代入の都度「置き換え」ではなく「追記」になります(文字列の場合。数値の場合は加算)。
つまり、
$line += '"{0}",' -f $user.Enabled
を冗長な書き方に直すと、
$line = $line + ('"{0}",' -f $user.Enabled)
ということになります。
文字列の「-f」については以下を参照してください。
URLリンク(www.google.com)
オブジェクトのプロパティを指定したものを文字列に直接記述できないのでこうしています。
(こうは書けない $line += '"$user.Enabled",')
307:300
20/06/04 21:01:19.40 7LqTXEt1.net
>>306
解説までいただきましてありがとうございます!
ご提案のスクリプトで無事、第1段階のデータを出力することができました。
次の作業がまた待っていますが、教えていただいたことを参考に
作ってみます。
本当にありがとうございます。
308:デフォルトの名無しさん
20/06/04 22:31:22.80 sBE+PUel.net
powershell学習したいのですが、どのようなことからやっていけばいいでしょうか?
とりあえず、バッチファイルを書き換えようかなぁとか思ったりしていますが
いかがでしょうか?
309:デフォルトの名無しさん
20/06/04 22:43:28 7Yb6fwZR.net
自分で書いたバッチファイルを置き換えるのは効果的な学習だと思う
ただ対応するコマンドを置き換えていくだけだと
オブジェクトをパイプでつないでいくPowerShellっぽい部分を身につけるのが難しいから
Cookbook的な本で先人のコードを写経しつつ改変していくのがいいんじゃないかな
310:デフォルトの名無しさん
20/06/04 23:21:46.10 hC0MsN2x.net
Ruby の方がよい。
Ruby 内で、powershell, clip コマンドなども呼べる
# クリップボード内の複数行文字列の、各行の先頭・末尾から、
# 連続する空白類を除去して、クリップボードに入れる
str = `powershell Get-Clipboard`
str.encode! Encoding::UTF_8, Encoding::CP932 # UTF_8 へ変換
ary = str.each_line.map( &:strip ) # 連続する空白類を除去する
IO.popen( 'clip', 'w:cp932' ) do | clip | # CP932 へ戻す
clip.print( ary.join "\n" )
end
311:デフォルトの名無しさん
20/06/05 01:16:33.38 amrr7gLk.net
URLリンク(heetnote.com)
ここで公開されているスクリプトを自分なりに書き換えて使っているのですが、
FakeAacWavをfre:ac1.11に置き換えるとWrite-Hostで表示される日本語が全て文字化けするようになってしまいました。
以前はfre:ac0.9を使っていたのですが、その時は文字化けしませんでした。
処理開始時点では日本語は正常に表示されるのですが、fre:acの処理が始まると同時に、正常に表示されていたものも含めて
全ての日本語が「□□□」に置き換わるようになります。
多分ですが文字コードの問題ではないようです。ソフト側の問題であってどうしようもないものでしょうか?
312:デフォルトの名無しさん
20/06/05 06:07:06.84 Trob9zBU.net
コマンドラインに その① を張り付けると その だけになるの困る
なぜか ① 単独で張り付けると ① が入るのが謎
①あ①あ だと ①ああ だったりもう……
313:デフォルトの名無しさん
20/06/05 08:46:16.13 S6jGROW/.net
>>311
外部コマンド(*.exe)の出力が起因する問題なのであれば、
「& ~~」で同一のコンソール内で実行するのではなく、
「Start-Process ~~~」で実行してみてはどうでしょう。
Start-Process の場合は新しいコマンドプロンプトのウィンドウが開いて、
そこで実行されます。
314:デフォルトの名無しさん
20/06/05 15:49:55 amrr7gLk.net
>>313
ありがとうございます。試行錯誤しているのですがStart-Processでfre:acが起動しません…
Start-Process -FilePath (fre:acのパス。""で囲む) -ArgumentList (fre:acの引数。""で囲む)
…で書式は合ってますよね?
315:デフォルトの名無しさん
20/06/05 16:56:17.03 S6jGROW/.net
>>314
CLI の外部コマンドは ※ 上で実行しますので、Start-Process で起動するのは
あくまでも ※ です。ですので、引数として CLI の外部コマンドを指定するといいと思います。
こんなかんじですかね。
URLリンク(pastebin.com)
※ コード内の文字列が5ちゃんの NG ワードになっていて書き込めないので、Pastebin にしました
316:デフォルトの名無しさん
20/06/05 17:15:12.53 O//h2yE5.net
初心者です。
あるlogフアイルの1行目を新しいlogファイルに書き出し、
続けて同じlogファイルから特定の文字列で検索した結果を上書きしたいのですが、
具体的には
Get-Content C:\test\stdout.log -totalcount 1 > C:\test\stdout_bk.log
Select-String -Path C:\test\stdout.log -Pattern 2020/0 -Encoding default >> C:\test\stdout_bk.log
こう書いてしまうとstdout_bk.log ファイルの2行目が改行してしまいます。
(3行目からSelect-String の結果がかき出される)
stdout_bk.log ファイルの2行目からSelect-String の結果をかき出したいのですが
どうすればいいでしょうか。また処理全体を2行に分けるのではなく
できたら1行にまとめたいのですが、可能でしょうか。
317:デフォルトの名無しさん
20/06/05 17:50:49.18 Trob9zBU.net
>>316
これであってる?
Get-Content C:\test\stdout.log | & { Begin { $header = $true } Process { if ($header) { $_; $header = $false } elseif ($_ -match '2020/0') { $_ } } > C:\test\stdout_bk.log
318:デフォルトの名無しさん
20/06/05 17:53:48.63 amrr7gLk.net
>>315
丁寧な解説ありがとうございます。しかしうまくいかない…。
ひょっとして外部コマンドになるので引数にPowerShellの変数を使用できないですか? こんな感じですが↓
Start-Process "一部省略" -ArgumentList ("/c","freacのパス","-e sndfile-wave -d $OutputDir $AacItem.FullName")
319:デフォルトの名無しさん
20/06/05 18:06:39 S6jGROW/.net
>>318
$AacItem.FullName を「"」で囲っても、$AacItem のプロパティ FullName は取り出せないです。
いろんなやり方があると思いますけど、私は「-f」を使うやり方が好みです。
Start-Process "一部省略" -ArgumentList ("/c","freacのパス",("-e sndfile-wave -d $OutputDir {0}" -f $AacItem.FullName))
でもこっちのほうが良さそうですね。
Start-Process "一部省略" -ArgumentList ("/c","freacのパス","-e","sndfile-wave","-d",$OutputDir,$AacItem.FullName)
320:デフォルトの名無しさん
20/06/05 18:11:37 S6jGROW/.net
>>318
$OutputDir や $AacItem.FullName にスペースが含まれてると失敗するかもしれませんので、その場合はこうでしょうか。
Start-Process "一部省略" -ArgumentList ("/c freacのパス -e sndfile-wave -d '{0}' '{1}'" -f $OutputDir,$AacItem.FullName)
321:デフォルトの名無しさん
20/06/05 18:22:39 O//h2yE5.net
>>317
}を1個つけると意図する結果が出力されました
ありがとうございました。
復習します。
322:デフォルトの名無しさん
20/06/05 18:52:19 O//h2yE5.net
>>317
すみません、よろしければ少し解説いただけないでしょうか
$_の使い方がいまいち理解できません。
323:デフォルトの名無しさん
20/06/05 19:56:13.96 amrr7gLk.net
>>319
3つとも試してみましたが、どれも正常に動きませんでした…。
一番上は何も処理せずpowershellが終了してしまい、2番めと3番めは黒いウインドウが一瞬表示されるものの
freacは何も処理せず次に進んでしまいました。
{0}と-fは
URLリンク(yanor.net)
ここの一番上で解説されているものでしょうか。
324:デフォルトの名無しさん
20/06/05 20:50:39.26 Trob9zBU.net
>>322
Processブロックでは $_ に各行が入ってくるので必要な時だけ出力しました
$_の扱いはForEach-Objectと同じなので、そちらでたくさん例が見つかるでしょう
>>323
Windows限定かもしれませんが、コマンドラインで
prog arg1 arg2 arg3
と起動するプログラムならこれでいい気がします
Start-Process "prog" -ArgumentList @('arg1 arg2 arg3')
325:デフォルトの名無しさん
20/06/05 21:15:18.94 Trob9zBU.net
例をつけ忘れました。こんな感じ。
Start-Process 'pwsh' -ArgumentList @('-nop -c "1 .. 3 | % { $_; Start-Sleep 1 }"')
326:デフォルトの名無しさん
20/06/05 21:44:06.19 amrr7gLk.net
Start-Process "freacのパス" -ArgumentList @('-e sndfile-wave -d $OutputDir $AacItem.FullName')
単純にこれではダメでした。
327:デフォルトの名無しさん
20/06/05 22:10:21.57 Trob9zBU.net
そりゃもちろんこうしないと
$args = '-e sndfile-wave -d {0} {1}' -f $OutputDir, $AacItem.FullName
Start-Process "freacのパス" -ArgumentList @($args)
328:デフォルトの名無しさん
20/06/05 22:12:15.54 Trob9zBU.net
ってこれ >>320 に空白考慮版があるね
329:デフォルトの名無しさん
20/06/05 22:17:17.85 Trob9zBU.net
と思ったけど >>320 は必要ないcmd(?)経由に失敗してる?
330:デフォルトの名無しさん
20/06/05 23:21:02.62 C2qeZTUp.net
>>324
もう一つご教示ください。
header変数はどこで定義されている(という表現が適切か判りませんが)か教えていただけないでしょうか
331:デフォルトの名無しさん
20/06/05 23:41:51.74 e4Todh9J.net
>>317
の、Begin { $header = $true }
Begin 節で、header という変数を定義して、初期値をtrue にしてるのでは?
332:デフォルトの名無しさん
20/06/05 23:44:42.07 C2qeZTUp.net
ありがとうございます。
理解できてない。無知をさらけ出してしまいました。
333:デフォルトの名無しさん
20/06/06 00:12:58.72 7YMZq5d4.net
>>312
①、つまり丸囲みの1 は、CP932 だけの環境依存文字だろ。
UTF-8 で使えるのかどうか、不明
ひょっとして、ファイル名に、半角英数字以外を使っているのか?
ファイル名・ユーザー名みたいなシステムに、半角英数字以外を使ったら、ダメ!
334:326
20/06/06 00:36:27.86 YeDbVwYY.net
>>372
すみません、それも結果は同じでした。
ここまで色々出していただいた記述例を全て試しても結果は同じで、cmdのウインドウは一瞬出るがfreacは何もせず終了という状態です。
プログラムに触るのが初めてというレベルの初心者で、ここで教えてもらったことを丸写しするくらいしかできないですか、
このままこの話題続けても大丈夫ですか? 大分長いこと占領していて申し訳ないのですが。
335:デフォルトの名無しさん
20/06/06 01:43:36 7YMZq5d4.net
Powershell で文字コードを変更する(clip.exe へのリダイレクトもね)
URLリンク(www.vwnet.jp)
「powershell 文字コード 変換」で検索!
本当は、込み入った処理は、Ruby でやって、
Powershell・コマンドプロンプトは、 起動部分だけの単純なものにすべき!
こういうシェルで、ややこしいプログラミングは無理
336:デフォルトの名無しさん
20/06/06 07:05:00.74 +ifRGkAL.net
>>312
>>251-254 のバグとは別かな?
337:デフォルトの名無しさん
20/06/06 07:07:30 3KBpE/OI.net
>>334
ようするに
$OutputDir = どこそこ
foreach ($InputItem in $Args) {
というループの中に
$AacItemList = Get-ChildItem 以下略
foreach ($AacItem in $AacItemList) {
というループがあって
& $fawclPath $AacItem.FullName
を書き換えて >>318 のようにしたいって理解であってますか?
なら $args を書き換えて使っちゃだめですし、
Start-Process も -Wait を付けた方が良さそうなんで
Start-Process 'freacのパス' -ArgumentList @('-e sndfile-wave -d "{0}" "{1}"' -f $OutputDir, $AacItem.FullName) -Wait
じゃないかな
338:デフォルトの名無しさん
20/06/06 07:08:59 3KBpE/OI.net
>>336
それだ!
でもPSReadLineなしでは不便過ぎる……
339:デフォルトの名無しさん
20/06/06 09:15:40.96 hmicP46W.net
PowerShellで多重ループが許されるのは小学生までだよね
340:319
20/06/06 09:23:51.93 2MzuylRm.net
>>323
こちらでも freac を入手して試したところ、>>319 のとおりで動作してます。
私は以下のようにして実行してみました。freac は ZIP で配布されていたものです。
※5ちゃんのNGワードに引っかかりまくって全く書き込みが出来ないため、コードは全て以下の Pastebin に記載しています
URLリンク(pastebin.com)
# パラメータ
# 例1
実際に試したところ、freac は ※ 経由でなくても動作しますね。
# 例2
【切り分け】
Start-Process で外部の CLI コマンドを実行した場合、終了後にウィンドウが
閉じられるので切り分けが難しくなります。
そこで、「-NoNewWindow」オプションを付けて実行してみてください。
freac (又は※) が出力するエラーが、PowerShell のコンソールに表示されるはずです。
# 例3
# 例4
【-f について】
{0} と -f に関してはご指摘のとおりです。
341:デフォルトの名無しさん
20/06/06 10:08:38 B/uunGh7.net
>>333
横レスだが、
> ?、つまり丸囲みの1 は、CP932 だけの環境依存文字だろ。
> UTF-8 で使えるのかどうか、不明
UTF-8というか、Unicodeには、一般的に使われている全ての
文字コードの全ての文字が含まれている。だから、Unicodeと呼ばれる。
> ひょっとして、ファイル名に、半角英数字以外を使っているのか?
> ファイル名・ユーザー名みたいなシステムに、半角英数字以外を使ったら、ダメ!
それはNEETの発想だ。職場の共有ファイル、取引先とやりとりする
ファイル等、一般社会では、ガチガチにファイル名のルールが規定
されていて自分勝手に決められない場合が多いのだよ。
342:デフォルトの名無しさん
20/06/06 10:17:39.94 3KBpE/OI.net
>>340
端末設定を変えられて文字化けするから Start-Process させるんでしょ
-NoNewWindow で端末共有させたらエラーメッセージも化けてるんじゃ……
Start-Process のパラメーターを画面出力して Start-Process せずに exit
出力されたパラメーターが正しいか確認……かな
それをスレに貼ってもらえれば即解決な気がする
343:319
20/06/06 10:55:21.17 2MzuylRm.net
>>323
すみません、これまでの Start-Process の例では「-Wait」オプションが抜けていました。
そのうえで、>>342 の指摘も考慮して以下の通り3パターンでテストしてみました。
URLリンク(pastebin.com)
test1.ps1
Start-Process を使用するバージョン(-NoNewWindow 無し)
test2.ps1
Start-Process を使用するバージョン(-NoNewWindow 有り)
test3.ps1
オリジナルに近いバージョン(外部コマンドを「&」で実行)'
結果は以下の通りです。
URLリンク(i.imgur.com)
test1.ps1、test2.ps1 が動作するのは想定どおりなのですが、test3.ps1 でも文字化けしてないんですよね・・・。
これまで「外部コマンドを Start-Process で別ウィンドウで実行すれば文字化けしない」という前提で
話を進めてきましたが、まったく関係なかったかも知れません。
344:デフォルトの名無しさん
20/06/06 11:30:16 7wZTkIMZ.net
外部コマンドの出力をpowershell側で触ったら文字化けするって話してるなら
最初にコンソール出力時のエンコーディング設定変えて
$defaultEncoding,[Console]::OutputEncoding = [Console]::OutputEncoding,[Text.Encodi ng]::UTF8
最後に戻してやればいいんじゃない
[console]::OutputEncoding = $defaultEncoding
345:デフォルトの名無しさん
20/06/06 13:53:01 3KBpE/OI.net
ちょっと話が脇にそれるんだけど……
あれ?
>>311 を読んで「表示済みの文字まで化ける」謎現象だと思ってたけど
「正常表示できてた文字を、新しく出力すると化ける」だけなの?
化けるのがコンソールアプリの出力だけで、PowerShellのその後の出力は正常なら
端末の受け入れるエンコーディングが変更されただけかも
出力関係のエンコーディングは
(a) コンソールアプリの出力を PowerShell がパイプなり代入なりで受け取る場合のエンコーディング (PowerShellが持ってる)
(b) 端末が受け入れるエンコーディング (端末が持ってる)
があって、PowerShell自身は勝手に(b)に合わせて出力するから化けない
コンソールアプリの出力は、PowerShellに食われる時は、(a)なら正常、違えば化ける
食われず直接端末に出力する時は、(b)なら正常、違えば化ける
コンソールアプリに(b)だけ変更されたのなら(a)に再設定すればいい
[console]::OutputEncoding を設定すると(a)と(b)の両方が設定される
(a)は [console]::OutputEncoding だから
[console]::OutputEncoding = [console]::OutputEncoding
すれば十分な気がする
346:326
20/06/06 13:53:57 YeDbVwYY.net
色々ありがとうございます。
まず結論ですが、>>344さんの方法で文字化けは一応治りました。
ただ、最初の行に
$defaultEncoding,[Console]::OutputEncoding = [Console]::OutputEncoding,[Text.Encodi ng]::UTF8
を記述すると
[console]::OutputEncoding = $defaultEncoding
が実行されるまで日本語が全て文字化けします。
なのでfreacが実行される行の上下をこれで挟むのが一応の解決方法でしょうか。
他の方々の書き込みですが、まずStart-Processに-waitをを付ける方法では完全に動作が停止して次の処理に進みませんでした。
>>340さんの例3、4を試してみると、File Not Foundになります。
原因が気になるところではありますが、本末転倒なので>>344さんの方法でとりあえず解決したことにします。ありがとうございました。
347:デフォルトの名無しさん
20/06/06 16:15:55 3KBpE/OI.net
[console]::OutputEncodingの退避・復元で解決できるなら
退避なんかせずに freac(?) の実行直後に
[console]::OutputEncoding = [console]::OutputEncoding
入れるだけでいい気がするけど、もういいや
348:デフォルトの名無しさん
20/06/06 17:37:53.88 7YMZq5d4.net
書き込み禁止ワードは、何かのコマンドだろ
cmd.@exe, ls @-l
外人のアプリだから、アプリ内部で、文字コードをASCII に決め打ちしてるのかも。
でも、そのアプリは、起動したPowerShellが親だとすると、子プロセスになるから、
子プロセス内で環境を変えたとしても、親プロセスに伝播しないだろ
親プロセスで環境を指定したら、子プロセスにその環境は引き継がれるけど
それかそのアプリは、文字コードをバイナリにしてるとかで、
データを受け取る方がテキストで受け取ると、文字化けするとか
349:デフォルトの名無しさん
20/06/06 18:47:57.73 2MzuylRm.net
>>344
それ良いですね、勉強になります。
「俺専用ナレッジベース」にメモしときました。
350:デフォルトの名無しさん
20/06/09 16:01:29.47 DriXa/wG.net
rem ff.cmd
@echo off
setlocal
cmd /k "pwsh -File ".\firefox-shutdown.ps1""
# firefox-shutdown.ps1
Start-Sleep -Seconds 10;
Get-Command;
Start-Sleep -Seconds 3;
Get-Process firefox* | Stop-Process;
351:デフォルトの名無しさん
20/06/09 16:26:23 DriXa/wG.net
Start-Sleep -Seconds 10;
mspaint "010371104.gif";
Start-Sleep -Seconds 3;
Get-Process firefox* | Stop-Process;
352:300
20/06/11 17:55:09 fJWIdGby.net
教えてください。
ADユーザーの最新ログオン日時を取得したいです。
記述としては、
$Now = Get-Date -Format 'yyyyMMdd_hhmmss'
$logPath = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ('{0}.csv' -f $Now )
$users = Get-ADUser -Filter * -SearchBase " OU=ユーザー,DC=test,DC=local "
foreach ($user in $users) {
Write-Host ('{0} : ' -f $user.SamAccountName) -NoNewline
$grps = (Get-ADPrincipalGroupMembership -identity $user).name
$line = '"{0}",' -f $user.SamAccountName
$line = $line + ('"{0}",' -f $user.Enabled)
$line = $line + ('"{0}",' -f $user.LastLogon)
と思いましたが、最終ログオン日時を取得するのは
LastLogonであっているでしょうか?
また、最終ログイン日時の後にフルネームを取得したいときは、
$Now = Get-Date -Format 'yyyyMMdd_hhmmss'
$logPath = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ('{0}.csv' -f $Now )
$users = Get-ADUser -Filter * -SearchBase " OU=ユーザー,DC=test,DC=local "
foreach ($user in $users) {
Write-Host ('{0} : ' -f $user.SamAccountName) -NoNewline
$grps = (Get-ADPrincipalGroupMembership -identity $user).name
$line = '"{0}",' -f $user.SamAccountName
$line = $line + ('"{0}",' -f $user.Enabled)
$line = $line + ('"{0}",' -f $user.LastLogon)
$line = $line + ('"{0}",' -f $user.Fullname)
となるでしょうか?
353:デフォルトの名無しさん
20/06/12 09:35:33.43 IRe5SA+Y.net
v6.2.6
URLリンク(github.com)
v7.0.2
URLリンク(github.com)
354:デフォルトの名無しさん
20/06/12 10:07:01.73 tUTXhBxn.net
>>352
Get-ADUser は、デフォルトでは一部のプロパティしか取得しません。"LastLogon" が必要な場合は -Properties で指定する必要があります。
$users = Get-ADUser -Filter * -SearchBase "OU=ユーザー,DC=test,DC=local"
↓
$users = Get-ADUser -Filter * -SearchBase "OU=ユーザー,DC=test,DC=local" -Properties 'LastLogon'
さらに、LastLogon で取得される日時データはシリアル化されたものですのでヒューマンリーダブルに変換する必要があります。
$line = $line + ('"{0}",' -f $user.LastLogon)
↓
$date = [DateTime]::FromFileTime($user.LastLogon)
$line = $line + ('"{0}",' -f $date.ToString("yyyy/MM/dd HH:mm:ss"))
「フルネーム」ですが、プロパティとしては Name が該当するものになります。
$line = $line + ('"{0}",' -f $user.Fullname)
↓
$line = $line + ('"{0}",' -f $user.Name)
355:354
20/06/12 10:07:36.18 tUTXhBxn.net
まとめるとこうです(ファイル書き出しの部分は省略)。
$users = Get-ADUser -Filter * -SearchBase "OU=ユーザー,DC=test,DC=local" -Properties 'LastLogon'
foreach ($user in $users) {
Write-Host ('{0} : ' -f $user.SamAccountName) -NoNewline
$grps = (Get-ADPrincipalGroupMembership -identity $user).name
$line = '"{0}",' -f $user.SamAccountName
$line = $line + ('"{0}",' -f $user.Enabled)
$line = $line + ('"{0}",' -f $user.Name)
$date = [DateTime]::FromFileTime($user.LastLogon)
$line = $line + ('"{0}",' -f $date.ToString("yyyy/MM/dd HH:mm:ss"))
Write-Host $line
}
356:354
20/06/12 10:09:03.73 tUTXhBxn.net
ただし、私自身も 10 年くらい前に AD の情報から LastLogon を取得することを検証したのですが、以下の理由から断念しました。
・LastLogon のデータは各ドメコンが個別に保持しているデータなので、ドメコンが複数ある場合は各ドメコンごとに値が異なる
(各クライアントが認証要求を行ったドメコンでしか更新されず、各ドメコン間で同期されない)
・ユーザが PC でログオンしたタイミング以外でも、LastLogon は更新される (ログオフや長時間離席していた場合など)
正確なログオン日時が取りたい場合は、各クライアント上で取得する必要があります。イベントログを見れば分かります。
私は結局、ファイルサーバのテキストファイルにログオン日時とユーザ名を書き込むログオンスクリプトを作成したと記憶しています。
357:354
20/06/12 10:22:05.71 tUTXhBxn.net
追伸。
>・LastLogon のデータは各ドメコンが個別に保持しているデータなので、ドメコンが複数ある場合は各ドメコンごとに値が異なる
全てのドメコンから値を取得して、最も値の大きいものを採用する、というやり方も出来ます。
それでも、LastLogon がログオン操作以外でも更新されてしまうことには変わりませんので、確実に実行するならやはりログオンスクリプトをおすすめします。
358:デフォルトの名無しさん
20/06/12 16:10:21.89 6Yfh5mGy.net
Power Shellってアプリケーション作れんですか?
359:デフォルトの名無しさん
20/06/12 18:18:25.00 Jkz+gOtE.net
アプリケーションって何?
360:デフォルトの名無しさん
20/06/12 18:44:27.27 /dqGhWwV.net
>>358
普通に作れるよ
GUIもWPF使えるし
361:デフォルトの名無しさん
20/06/12 18:45:58.91 gCbNSmDh.net
window表示するイベントドリブンなexeのことじゃないかな
362:デフォルトの名無しさん
20/06/12 18:55:49.90 tr06rVi2.net
もうそれ最初からC#でやれば良くね?っていう
363:デフォルトの名無しさん
20/06/12 19:42:03.65 sTuFS1ZK.net
大部分C#で書いてパワシェで書きやすい部分だけデリゲートでインジェクションするパターンなら多用しとるわ
364:デフォルトの名無しさん
20/06/12 20:21:21.09 6LTYSgwt.net
ただのコマンドプロンプトだと思ってた
スゲーワケわからん
365:デフォルトの名無しさん
20/06/12 20:53:03.96 tSkvENox.net
オブジェクト指向シェル言語だからな
366:300
20/06/14 00:11:44.27 JXZUsp2d.net
>>354
ありがとうございます!
検証環境で無事出力確認できました!
しかし最終ログイン日時の取得は難しいんですね。
今回はそれほど精密な値は求められないので良かったですが、
ドメコンには注意なんですね。
367:デフォルトの名無しさん
20/06/15 19:20:43.36 KO8t20+1.net
ドメコンにリアルタイム性は期待できないと思ったがやっぱそうだよな
368:デフォルトの名無しさん
20/06/16 08:27:08.93 flP7FZNr.net
LastLogin を各DCから拾って最新値を取り出すスクリプトあったよ
URLリンク(gallery.technet.microsoft.com)
369:デフォルトの名無しさん
20/06/16 11:32:29.65 r0rBA9XG.net
コマンドプロンプトでecho a b cを実行すると出力結果は
a b c
PowerShellでecho a b cを実行すると
a
b
c
なのはなんで?
エラーにもならずにbやcはどう扱われてるの?
370:デフォルトの名無しさん
20/06/16 11:55:26.03 dJYiaODe.net
echo a b c
とかやってみれば、以下にcmdがクソかよくわかると思うよ。
371:デフォルトの名無しさん
20/06/16 11:56:36.32 dJYiaODe.net
あ、間のスペースも消えてなくなるのか。
echo___a_____b____c
_をスペースに。
372:デフォルトの名無しさん
20/06/16 12:32:39 0Yfa1k+l.net
いやいやいや
引数なんだから当然だろ
あとは出力で改行するかどうかだけじゃん
373:デフォルトの名無しさん
20/06/16 12:44:08.30 zfRgO9so.net
echo "a b c"
" " で囲えば、a b c
と表示される
374:デフォルトの名無しさん
20/06/16 12:53:01.50 r0rBA9XG.net
聞きたいのはそういう類じゃないんだな
echo (=Write-Output) のSyntaxが
Write-Output [-InputObject] <PSObject> [-NoEnumerate] [<CommonParameters>]
だからa が-InputObjectの<PSObject>になるのはわかる
bやcはどういう理屈で処理されるの?
375:デフォルトの名無しさん
20/06/16 14:16:42.05 PL2rwu//.net
>>374
echo a b c
は
echo @('a', 'b', 'c')
と同じ扱いとするように実装されてるんでしょ
376:デフォルトの名無しさん
20/06/16 14:40:34.28 p9YvTGLE.net
まあ調べた374がpowershellの引数展開についてまとめて分かりやすく報告してくれるでしょ
377:デフォルトの名無しさん
20/06/16 14:48:49.11 C/0BZ8DU.net
MSの説明では、正確には
[-InputObject] <PSObject[]>
となってる
378:デフォルトの名無しさん
20/06/16 16:42:16.77 r0rBA9XG.net
del a b cはちゃんとエラーになる
さっぱりわからん😩
379:デフォルトの名無しさん
20/06/16 17:12:01.69 MVe0R048.net
Write-Outputの-InputObjectパラメータにはValueFromRemainingArguments属性がついてるから
その場合はパラメータ名が明示されてないものはすべてInputObjectにバインドされるんよ
確認はしずらいけど以下で確認できる
(Get-Command Write-Output).ParameterSets[0].Parameters | where name -eq InputObject
まああんまりこの属性ついてるのはないからecho とかWrite-Hostあたりはこうなってるくらいの認識でいいよ
PowerShell7だとJoin-Pathもこの属性がついてる
380:デフォルトの名無しさん
20/06/16 17:24:04.82 8ZMUuPb8.net
echoの引数がUNIXとかだとアレだよ
381:デフォルトの名無しさん
20/06/16 17:25:39.53 MVe0R048.net
>>379
訂正:パラメータ名が明示されてないものでポジショナルバインディングもできないもの
382:デフォルトの名無しさん
20/06/16 17:45:58 r0rBA9XG.net
なるほど
ありがとう
383:デフォルトの名無しさん
20/06/16 19:16:29.09 bkoiHKSB.net
PowerShellの起動がなんか凄いモタつくんだけどおまかん?
Windows10Home PS7.01
スクリプト書いて渡しても、
何も出ない黒い画面がしばらく出て怖がられたり、何個も起動されたりするし
384:デフォルトの名無しさん
20/06/16 21:23:47.76 aR46ypRq.net
>>251,312
右クリックじゃなくてCtrl+Vではどう?
385:デフォルトの名無しさん
20/06/16 22:43:53.36 Tk9CpyzQ.net
cmd -L
9875 shinjyuku Tokyo Japan
の1列目を1行で変数に格納したいのですが、方法がわかりません。
$work=(cmd -L | Select-String "shinjyuku" )
$id=$work -split " "
Write-Output $work[1]
これを1行で書ける方法を教えてください。
よろしくお願いいたします。
386:デフォルトの名無しさん
20/06/16 23:40:23 n71ojSL1.net
cmd -Lが何なのか判らないのでcmd /c echoの例で
(cmd /c echo 9875 shinjyuku Tokyo Japan | %{ $_ -split " " })[0]
387:デフォルトの名無しさん
20/06/16 23:41:31 n71ojSL1.net
忘れてた頭に$id=付けてね
388:デフォルトの名無しさん
20/06/17 07:40:39.83 0yXiYm7U.net
>>386
ありがとうございます
特に隠すようなコマンドでもなかったのですが、
インターネット速度の自動計測スクリプトを作ってみようとしてます
.>\speedtest.exe -L | select-string 'OPEN Project \(via 20G SINET\)'
15047 OPEN Project (via 20G SINET) Tokyo Japan
> $i=(.\speedtest.exe -L | select-string 'OPEN Project \(via 20G SINET\)' | %{$_ -split ' '}[0])
> Write-Output $i[1]
15047
389:デフォルトの名無しさん
20/06/17 07:50:00.92 PujUJ59z.net
cmd .exeに-Lオプションがあるのかと思った人は俺以外にもたくさんいるはず
390:デフォルトの名無しさん
20/06/17 08:00:55.98 H0Dcbe9T.net
VSCode で、PowerShell の拡張機能を入れると、構文チェックで、
Write-Host を、Write-Output か、Write-Verbose に変えろって警告される
PowerShell/PSScriptAnalyzer
URLリンク(github.com)
391:デフォルトの名無しさん
20/06/17 08:04:57.13 H0Dcbe9T.net
漏れは回線速度を、NETFLIX で測っている
URLリンク(fast.com)
392:デフォルトの名無しさん
20/06/17 10:09:26.78 U7B7s7qz.net
>>388
(.\speedtest.exe -L | select-string 'OPEN Project \(via 20G SINET\)' | %{$_ -split ' '}[0])[1]
393:392
20/06/17 10:13:28.30 U7B7s7qz.net
>>388
あれ、speedtest.exe の「-L」って、ネットワーク的に近い場所のサーバを
表示するだけで、実際の計測はしてないようですけど、これで良いんですか?
>>388 の続きがある、ってことですかね。
394:392
20/06/17 10:21:19.19 U7B7s7qz.net
>>388
タスクスケジューラで回すことを考えてるのかも知れませんが、単に
.\speedtest.exe -s 6766
とか
.\speedtest.exe -s 15047
といった感じにしないのはなぜですか?
speedtest.exe -L を実行する意図がよく分かりません。
395:392
20/06/17 10:29:32.27 U7B7s7qz.net
>>388
連投ごめんなさい、speedtest.exe は出力形式を CSV とか JSON とか色々
選べますので、ヒューマンリーダブルのものを加工するよりもそっちのほうが
簡単だと思います。
実行例:近隣サーバの列挙
PS > .\speedtest.exe -L -f csv
"ID","Name","Location","Country","Host"
"24333","Rakuten Mobile , Inc","Tokyo","Japan","ookla.mbspeed.net"
"15047","OPEN Project (via 20G SINET)","Tokyo","Japan","speed.open.ad.jp"
"28910","fdcservers.net","Tokyo","Japan","lg-tok.fdcservers.net"
~以下略~
実行例:サーバを指定した計測
PS > .\speedtest.exe -s 15047 -f csv
"OPEN Project (via 20G SINET) - Tokyo","15047","4.43","0.605","0","72540509","45781634","871440390","582254568","URLリンク(www.speedtest.net)
396:デフォルトの名無しさん
20/06/17 15:45:25.40 UcA8Gcsf.net
ジョブをパイプの途中で使いたいと考えています
1 .. 3 | % { $_; sleep 1 } | & { process { ">$_" }}
これは1秒間隔で結果が出ます
Start-Job { 1 .. 3 | % { $_; sleep 1} } | Receive-Job -wait
これも1秒間隔で結果が出ます
1 .. 3 | % { $_; sleep 1 } | Start-Job { process { ">$_" }} | Receive-Job -wait
これは結果がまとめて出ます
1秒間隔で結果を得るにはどうすれば良いのでしょうか
# パイプラインで入出力がsjisのコマンドとutf8のコマンドを通すのが最終目的です
# データ生成 | sjis入出力 | utf8入出力 みたいなイメージ
# パイプラインでエンコーディングを混在させるのに$OutputEncodingの方は
# スコープで分ければすみますが、[console]::OutputEncodingはスコープ無関係
# なのでジョブで分けようかと
397:デフォルトの名無しさん
20/06/17 16:28:19.33 pLBooGKC.net
なんでワンライナーでやる必要があるのかね、こういうの
保守とか考えないのかね
398:デフォルトの名無しさん
20/06/17 16:55:10.36 /58stVp5.net
パイプの弊害か
399:デフォルトの名無しさん
20/06/17 17:44:32.75 UcA8Gcsf.net
>>397
コマンドラインで結果をすぐに見たいからですね
ページャーにつないで欲しい結果が出てきたら確認して終了
ステップごとに完了待ちしてたら時間がもったいない
400:デフォルトの名無しさん
20/06/17 23:59:11.03 H0Dcbe9T.net
>>396
>1 .. 3 | % { $_; sleep 1 } | Start-Job { process { ">$_" }} | Receive-Job -wait
1 .. 3 | % { $_; sleep 1 }
この部分を、Start-Job の中に入れたら?
401:デフォルトの名無しさん
20/06/18 05:52:46 7bz/apiR.net
$ary_names = @('太郎','次郎','三郎','四朗','五郎')
write-output $ary_name[@] #bashの記法
太郎,次郎,三郎,四朗,五郎
的なことをしたい。※区切り文字はなんでも可。
現状、配列に文字列をくっつけると1行で出るので
write-output ("a"+$aaa).trim("a")
という強引な方法をとっております。もっとPowershell的にスマートな方法があれば
お教えくださいませ。
402:デフォルトの名無しさん
20/06/18 06:58:53 3wPjj0xg.net
$ary_names -join ','
403:デフォルトの名無しさん
20/06/18 07:18:11.97 7bz/apiR.net
>>402
ありがとうございます!
404:デフォルトの名無しさん
20/06/18 09:01:24.17 hwvpLd3O.net
>>400
それだと最終目的のためにはStart-Jobの入れ子が必要になるなあ
制御不能になりそうだし面倒なので避けたい
cmd.exeを使うことにします
405:デフォルトの名無しさん
20/06/19 06:41:17 RNyMoV2a.net
$s=[datetime]::Now; 1 .. 5 | ForEach-Object { Start-Sleep 1; ">{0}" -f $_ } | ForEach-Object { Start-Sleep 1; ">{0} {1}" -f $_, ([datetime]::Now - $s).TotalSeconds}
2秒間隔、トータル10秒という結果に困惑している
406:デフォルトの名無しさん
20/06/19 07:30:31.94 JIIBGf6G.net
>>405
二重ループを期待してたってこと?
407:405
20/06/19 08:42:12.76 RNyMoV2a.net
最初は2秒、それから1秒間隔でトータル6秒だと思ってた
1秒待ちをStart-Sleepでなく別のプロセスで待たせても変わらなかった
408:デフォルトの名無しさん
20/06/19 08:51:47 GhHOGZr1.net
パイプつなぎはいわゆるgenerator(PowerShellでの呼び方は知らない)になるってことかな?
409:デフォルトの名無しさん
20/06/19 08:52:39 JIIBGf6G.net
1に対して最初のfor-eachの中身処理した後に次のfor-eachの中身処理。
2に対して...
3に対して...
4に対して...
5に対して...
ふたつのfor-eachの中身がどういう順に処理されてるか確認できるように表示を工夫してみたら?
410:405
20/06/19 09:08:23.61 RNyMoV2a.net
そこはなんとなくイメージできたんでもういい
パイプラインの各段を別のプロセスにすると6秒で終了する
同じように6秒で終了すると思ってたら違ったんで戸惑ったというお話
411:405
20/06/19 11:12:17.79 RNyMoV2a.net
$s=[datetime]::Now; 1 .. 5 | Start-ThreadJob { process { Start-Sleep 1; ">${0}" -f $_ }} | Receive-Job -Wait -AutoRemoveJob | ForEach-Object { Start-Sleep 1; ">{0} {1}" -f $_, ([datetime]::Now - $s).TotalSeconds}
別スレッドを指定したらトータル6秒になった
一人研究発表会になっちまったな。すまぬ。
412:405
20/06/19 11:40:12.67 RNyMoV2a.net
よく見たら結果がおかしい。お手上げだ。諦めた。
413:デフォルトの名無しさん
20/06/19 17:20:54 qQd5c1Zr.net
>>397
おまえはpythonでもつかってろ
414:デフォルトの名無しさん
20/06/19 18:23:41.02 OOcqKGQK.net
ラクダが笑ってんぞ
415:405
20/06/19 21:01:31.39 RNyMoV2a.net
できたーーーー
$s=[datetime]::Now; 1 .. 5 | ForEach-Object { Start-Sleep 1; ">{0}" -f $_ } | ForEach-Object { Start-Sleep 1; ">{0} {1}" -f $_, ([datetime]::Now - $s).TotalSeconds}
にちょい足しして
$s=[datetime]::Now; 1 .. 5 | ForEach-Object -Parallel { Start-Sleep 1; ">{0}" -f $_ } -ThrottleLimit 1 | ForEach-Object { Start-Sleep 1; ">{0} {1}" -f $_, ([datetime]::Now - $s).TotalSeconds}
にしたらStart-ThreadJobを使った時より遅いけど簡単に予想してた結果になった
お騒がせしました
416:405
20/06/19 21:15:58.78 RNyMoV2a.net
こ、今度こそできたー
$s=[datetime]::Now; 1 .. 5 | Start-ThreadJob { $input | ForEach-Object {Start-Sleep 1; ">{0}" -f $_ }} | Receive-Job -Wait -AutoRemoveJob | ForEach-Object { Start-Sleep 1; ">{0} {1}" -f $_, ([datetime]::Now - $s).TotalSeconds}
やっぱりこれが最終版ということにしたい
お邪魔しました
417:デフォルトの名無しさん
20/06/20 00:50:50.12 na6pkPqz.net
はいつぎ
418:デフォルトの名無しさん
20/06/20 08:11:14.95 wKnheY+E.net
Powershellを使いこなすにはcomを知らなければならないと聞いたのですが、
comについてはどうやって学ぶのがオススメですか?
ググラビリティの悪い単語なので、
思うように検索できません
Excellの機能を使ってあれこれしたいです
419:デフォルトの名無しさん
20/06/20 09:03:13.32 5oXecify.net
COM の使い方
URLリンク(docs.microsoft.com)(v=msdn.10)
420:デフォルトの名無しさん
20/06/20 11:29:31 XppcwtFP.net
Powershellを使い始めました
皆さん、こんなの全部覚えてるんですか?
どうやって覚えました?
ファイル開いて書き込むだけで
こんなにもたくさん覚えないといけないって
大変だったんじゃないですか?
$output_file = "C:\bin\hoge.txt"
$sw = New-Object System.IO.StreamWriter($output_file, $false, [Text.Encoding]::GetEncoding("UTF-8"))
$sw.WriteLine("aaa")
$sw.WriteLine("あああ")
$sw.Close()
$sw.WriteLine("あああ")
$sw.Close()
この辺はまだ、覚えられるのですが、
New-Object System.IO.StreamWriter←InputOutputを、ストリームにライトするんだろうな
$output_file, $false, ←ファイル名と、追記、上書を指定するんだろうな。
[Text.Encoding]:: ←なんで[]包むんだ、:: ←このダブルのコロンは何だ、
GetEncoding("UTF-8")) ←何でファイル作ってるのにGetなんだ、
単純に
$mojiko-do="UTF-8"で
New-Object System.IO.StreamWriter($output_file, $false,$mojiko-do)じゃないんだと、
覚えることや、なぜこうなってるんだに少々ビビってます。
皆さんが、どうやってこんなに複雑で面倒なものを覚えたか、コツがあったら教えてください。
421:デフォルトの名無しさん
20/06/20 11:33:23 XppcwtFP.net
ほかにも、メソッド、プロパティ?クラス?で書き方がものすごいたくさんあるようで、めまいがします。
覚えれば仕事が楽になることは分かっているので、頑張りたいところなんですが
あまりの複雑さに、皆さんがどうやって覚えたのか、コツがあればぜひともお教えください。
422:デフォルトの名無しさん
20/06/20 11:46:07.33 6HpZ1NhN.net
良くも悪くも.NETが前提だから
先にC#を覚えるのがコツかな
423:デフォルトの名無しさん
20/06/20 12:28:41.13 sltMp+ny.net
コード量が多いってことと覚えなきゃいけない知識量は必ずしも一致しないからな
Perlみたいに省略できまくるワンライナーのほうがスパゲティったときわけ分からなくなる
424:デフォルトの名無しさん
20/06/20 12:29:17.17 dcvMDCGE.net
とにかく書いて動かす
やってみる、作ってみる
国語力、英語力は少しつけようとする
425:デフォルトの名無しさん
20/06/20 12:31:14.10 E6EedD+K.net
.NETなんて前提にしなくてもマルチプラットフォームで使える文法を身につけるのが先
426:デフォルトの名無しさん
20/06/20 13:13:11.69 w0A+CU3q.net
>>420
ファイルに書き込むだけならコマンドレットで足りる
痒い所に手が届かない時にググりながら.NETをボチボチ使って行けば良い
427:デフォルトの名無しさん
20/06/20 13:13:46.53 F3e6GYXo.net
正直言ってPowerShellは覚える必要ない
スクリプトファイルを作って使うならC#を使うのと大差ない
それならC#を覚えて使う方がいい
コマンドラインシェルとして使うなら.NETやらCOMやら取り込む使い方は
何かあった時にシェルが巻きぞえになって、シェルを殺すしかなくなる
そうならない程度に言語自体の機能だけで使うなら、とりたて覚えるほどでもない
428:デフォルトの名無しさん
20/06/20 13:42:16.03 dcvMDCGE.net
本番環境その場で場当たり的にコマンド打つのはあり得ないしな
まあすごくユルい会社なら知らんが
429:デフォルトの名無しさん
20/06/20 13:50:27.59 zwBEwaPL.net
>>420
その書き方は.NETライブラリを使っているのでPowershellの初歩の枠を越えてる
追記するだけならこう
$output_file = "C:\bin\hoge.txt"
"aaa" | Out-File $output_file -Append -Encoding UTF8
"あああ" | Out-File $output_file -Append -Encoding UTF8
こうしてもいい
"aaa", "あああ" | Out-File $output_file -Append -Encoding UTF8
UTF16でいいならこれ
"aaa", "あああ" >> $output_file
Powershell 5以前には欠陥があって、BOMなしUTF8を新規作成する簡単な手段がなかった
だからStreamWriterを持ち出すようなサンプルが普及していて、初歩のはずなのに難しいと感じる要因になってる
430:デフォルトの名無しさん
20/06/20 14:13:22.51 Xz+FX1Oy.net
必要はないけど覚えたら便利
431:デフォルトの名無しさん
20/06/20 14:35:58.75 YZMPfrl8.net
最初から暗記する必要はなくて、機能を一覧表にしておいて
必要に応じてそれを参照、コピペすればいい
出現頻度の高いものは自然と覚える
いずれにしても手打ちするのは時間の無駄なので
コピペ推奨
432:デフォルトの名無しさん
20/06/20 16:51:19.56 KBDfWM5t.net
習得してない人達のアドバイスは聞く必要がない
あっだからできないんだっていう見本にはなるけど
433:デフォルトの名無しさん
20/06/20 16:58:42.46 py+iqQxS.net
俺以外のアドバイスは聞く必要がない
434:デフォルトの名無しさん
20/06/20 17:35:07.43 6sC7z1nS.net
>>420
>コツがあったら教えてください。
PowerShell に限った話じゃないけど、学校の授業みたいに「勉強ありき」で
努力するよりも、「これをやるためには PowerShell を使うしか無い」という
状況に追い込まれると覚えやすいですね。
あと、積極的に英語のフォーラムなどから情報を得るようにしたほうが良いと思います。
やはり、日本語と英語では情報量が雲泥の差ですので。
Google 翻訳を使えば何とかなります。
435:デフォルトの名無しさん
20/06/20 20:10:35.90 WPfafdOl.net
>>434
> 「これをやるためには PowerShell を使うしか無い」という状況
そんな状況は、普通は無い。
あるとすれば、>>428が言った
> 本番環境その場で場当たり的にコマンド打つ
ぐらい。
436:デフォルトの名無しさん
20/06/20 23:24:31.04 tXS4Zxv6.net
PowerShell(PS)で、ビジネスロジック・複雑なものを書いたら、ダメ!
基本的に、CSV・JSON などは、Ruby で書いて、
起動部分だけを、コマンドプロンプト・PS・VBS などで作る
437:デフォルトの名無しさん
20/06/20 23:38:30.06 sltMp+ny.net
Pythonにしてくれ頼む
438:デフォルトの名無しさん
20/06/21 08:39:56.92 PKUYu7rs.net
>>435
>そんな状況は、普通は無い。
仕事で MS のエンタープライズ系製品を扱ってると、嫌というほど
そういう状況に遭遇しますね。
Windows Server, Exchange, SQL Server, Office 365 あたりの
設計、構築、運用に携わってれば日常茶飯事です。
そういう仕事に携わるようになってから PowerShell を覚えた、って人が
多いと思ったけど、そうでもないのかな?プログラム板だから違うのかな?
439:デフォルトの名無しさん
20/06/22 18:21:34.75 njZ7JPCW.net
>>0438
君は正常。
440:デフォルトの名無しさん
20/06/24 07:34:20.49 9MFoHisW.net
コマンドプロンプトでバッチを作るとちょっとした自動化に便利というのを最近知って調べたら
今はPowerShellCoreが現行とたどり着いたが
やっぱり移行するしないで揉めてる
441:436
20/06/24 08:08:25.26 rM4tv+8j.net
さすがに、バッチでプログラミングしてはいけない!
可読性が低すぎる
Ruby スクリプトなどを起動するだけにしておくべき
442:デフォルトの名無しさん
20/06/24 08:40:10 L+v/qVAN.net
>>440
用途・要件次第。
業務利用という前提だけど、自分だったらこういうポリシーで緩やかに移行する。
・既存の cmd バッチや WSF、VBS → 基本的には移行(移植)しない
※例外:改修が必要になった場合は個別対応
・新規 → 基本的には PowerShell で作るべき
※例外:極々単純なもの、自分だけが使い捨てするもの
443:デフォルトの名無しさん
20/06/24 08:44:24 /txx2vwO.net
可読性w
可読性に煩いやつ程低レベルだよね
三項演算子とか
444:デフォルトの名無しさん
20/06/24 09:05:28.99 W7e3ICMc.net
>>441
お前はRuby禁止のスレでRubyでは~Rubyでは~とやるのをやめろ。ノイズにしかならない糞レスはスレの可読性を下げるだけだ。
445:デフォルトの名無しさん
20/06/24 09:51:09 LpqCs0qI.net
440で思い出したけど、powershell coreって今どうなってるんや
自分は実行環境としては5.1をメインで使ってるけど、みんなどこら辺なんや
446:デフォルトの名無しさん
20/06/24 10:09:13.32 wIzfCOgT.net
win10プレインストールしか使っとらんわ
というかツール勝手に入れられない客先環境で戦うためのツールって認識
447:デフォルトの名無しさん
20/06/24 10:48:39.06 oYgVDO6A.net
>>446
> ツール勝手に入れられない客先環境で戦うためのツール
ほんそれ。
いまメインでやってる案件だと、お客さんから貸与されてる作業用 PC があって、
お客さんの環境にはそのマシンしか繋げられない。もちろん、世に数多とある便利ツールを
好き勝手に入れることは出来ない。
でも PowerCLI などの PowerShell モジュールのインストールは純正管理ツール扱いで
許可されてるので、構築とか保守作業では PowerShell スクリプトを使いまくってる。
いちいちマウスでカッチンカッチンやってたら、日が暮れちゃうからね・・・。
448:デフォルトの名無しさん
20/06/24 12:17:32.10 9MFoHisW.net
>>442
なるほど。
どうも。
449:デフォルトの名無しさん
20/06/24 21:01:47.98 jVaXlMW4.net
scriptblock[] を受け取って、scriptblockをそれぞれスレッドで動かして
パイプでつないで実行するfunctionを書きたいんだがうまく書けない
ようするに
$s = [datetime]::Now
1 .. 10 |
% { sleep 1; ">$_" } |
% { sleep 1; ">$_" } |
% { sleep 1; ">{0} {1} " -f $_, ([datetime]::Now - $s).TotalSeconds }
を実行すると
>>>1 3.1179897
>>>2 6.1354357
>>>3 9.1403334
>>>4 12.1434852
と3秒間隔で結果が出るんで
$s = [datetime]::Now
threadedpipe @( { 1 .. 10 },
{ % { sleep 1; ">$_" } },
{ % { sleep 1; ">$_" } },
{ % { sleep 1; ">{0} {1} " -f $_, ([datetime]::Now - $using:s).TotalSeconds }})
みたいに書いて、最初が3秒目で1秒間隔で結果出力したい
いろいろ試して諦めたんだが、そもそもPowerShellではこういうfunctionは書けないの?
450:デフォルトの名無しさん
20/06/24 22:06:24.12 VGKuFIs7.net
powershellのコマンドはプロセス作らないから無理じゃね
マルチスレッドをそんなお手軽に制御できたら夢みたいだけど
451:デフォルトの名無しさん
20/06/25 00:26:33.50 GAspYPHa.net
あれでもForeach-object あたりにparallelこなかったっけ
452:デフォルトの名無しさん
20/06/25 00:40:28.26 BtDpxRK3.net
並列に動かすってことは普通にやれば1秒間隔じゃなくてほぼ同時に出力されることになる
どういう意図なのかはわからないけど無理やりやるんなら入力側で一秒ずつ待ってやるか
$sw = [Diagnostics.Stopwatch]::StartNew()
1..10
| % { ">$_"; sleep 1 }
| % -pa { sleep 1; ">$_" }
| % -pa { sleep 1; ">$_" }
| % { "{0} {1:F2} " -f $_, $sw.Elapsed.TotalSeconds }
もしくは出力側で一秒ずつ待ってやるか
1..10
| % -pa { sleep 1; ">$_" }
| % -pa { sleep 1; ">$_" }
| % { sleep 1; "{0} {1:F2} " -f $_, $sw.Elapsed.TotalSeconds }
453:デフォルトの名無しさん
20/06/25 00:44:41.05 LTqYJW83.net
シェルスクリプトみたいに各プロセスが並列的に流れてくるテキストを処理して…
みたいのをやりたいのかなと推測してる
454:デフォルトの名無しさん
20/06/25 08:46:34.24 L3VdfOGw.net
そうそうそういうこと
イメージとしては URLリンク(ja.wikipedia.org)命令パイプライン
パイプラインのステージごとに1スレッド起動して全データで使いまわしたい
4ステージのパイプラインなら4スレッドで動かす
ForEach-Object の -Parallel はデータごとにスレッドを起動するから別物
スレッドプールで使いまわすにしてもちょっと違う
ちなみに sleep させてるけど時間がかかる処理の代用ね
455:デフォルトの名無しさん
20/06/25 08:53:56.13 L3VdfOGw.net
こっちの方がイメージが近いかも
URLリンク(ja.wikipedia.org)パイプ_(コンピュータ)
456:デフォルトの名無しさん
20/06/25 09:37:48.10 piKX+XZq.net
普通にワンライナー諦めれば次の作業にすすめるんじゃない?
457:デフォルトの名無しさん
20/06/25 09:50:30.28 L3VdfOGw.net
ワンライナーなんか関係ないんだけど
原理は >>416 にあるから、それを簡単に実現できるように
function threadedpipe { param([scriptblock[]] $sbs)
を書きたいと言ってる
458:デフォルトの名無しさん
20/06/25 09:56:30.77 1+fg5ofc.net
あぁまたこいつだったか
459:デフォルトの名無しさん
20/06/25 10:49:27.00 dZiolc11.net
>パイプラインのステージごとに1スレッド起動して全データで使いまわしたい
これが根本的に間違ってるだろ。
パイプで連結するってことは、前後(依存)関係があるってことで、それぞれをスレッド分割したところで全く意味がない。
460:デフォルトの名無しさん
20/06/25 11:16:02.92 L3VdfOGw.net
何言ってんの?
パイプラインってものをわかってない
これスクリプトファイルにして試してみ
function recvdata { foreach ($i in 1 .. 10) { sleep 1; $i }}
filter mul10 { sleep 1; $_ * 10 }
filter add1 { sleep 1; $_ + 1 }
filter fmtresult { "{0} {1}" -f $_, ([datetime]::Now - $script:s).TotalSeconds }
"スレッドなし"
$s = [datetime]::Now
recvdata | mul10 | add1 | fmtresult
"ステージごとに別スレッド"
$s = [datetime]::Now
Start-ThreadJob {
filter add1 { sleep 1; $_ + 1 }
Start-ThreadJob {
filter mul10 { sleep 1; $_ * 10 }
Start-ThreadJob {
function recvdata { foreach ($i in 1 .. 10) { sleep 1; $i }}
recvdata
} | Receive-Job -Wait -AutoRemoveJob | mul10
} | Receive-Job -Wait -AutoRemoveJob | add1
} | Receive-Job -Wait -AutoRemoveJob | fmtresult
461:デフォルトの名無しさん
20/06/25 11:35:16.74 emOdy//g.net
きたない
462:デフォルトの名無しさん
20/06/25 11:41:54.06 L3VdfOGw.net
んだからfunction threadedpipeを作って見やすくしたいっつってんだろ
463:デフォルトの名無しさん
20/06/25 12:35:03.44 WfI766VN.net
そこじゃないだろ
464:デフォルトの名無しさん
20/06/25 13:13:44.27 sZY/v5D+.net
>>462
単に興味本位で聞くんだけど、差し支えなかったら教えて。
具体的にどんなデータをどんな状況で処理しようとしてるの?