ファイル共有のアクセス許可を取得する
おなかがすいた。
Windows7に入ってるレベルのPowerShellでファイル共有のアクセス許可を取得してくるスクリプト。
ちょっときたないけどメモに残しておこうと思います。
これ、NTFSアクセス許可ではなく"ファイル共有アクセス許可"を取りに行く目的のスクリプトで、あまりネットで事例を見かけなくて苦労した。
ポイントは"Get-WmiObject win32_LogicalShareSecuritySetting"でファイル共有のセキュリティ設定をとってくるところ。
LogicalShareSecuritySettingで取れない管理共有とかは結果に出てこない。
$shares = Get-WmiObject win32_Share $result= @() foreach ($Share in $Shares){ $ShareSecuritySetting = Get-WmiObject win32_LogicalShareSecuritySetting ` -Filter ("Name='"+$Share.Name+"'") if(!($ShareSecuritySetting)){ continue } $acls = $ShareSecuritySetting.GetSecurityDescriptor().Descriptor.DACL foreach($ACL in $ACLS){ $Obj = @{} $obj["共有名"] = $Share.Name $obj["パス"] = $Share.Path $User = $ACL.Trustee.Name if(!($user)){$user = $ACL.Trustee.SID} $Domain = $ACL.Trustee.Domain switch($ACL.AccessMask) { 2032127 {$Perm = "Full Control"} 1245631 {$Perm = "Change"} 1179817 {$Perm = "Read"} } $Obj["アカウント"] = "$Domain\$user" $Obj["パーミッション"] = "$Perm" $result += New-Object PSObject -Property $Obj } } $result | Format-List
実行するとこんな感じ。
(前略) アカウント : lasty\bounoki パーミッション : Full Control 共有名 : test_share1 パス : R:\test_share1 アカウント : lasty\bounoki パーミッション : Full Control 共有名 : test_share2 パス : R:\test_share2 アカウント : BUILTIN\Administrators パーミッション : Full Control 共有名 : test_share2 パス : R:\test_share2 アカウント : lasty\motie パーミッション : Change 共有名 : test_share2 パス : R:\test_share2
参考にしたのはこちらのサイト。
http://www.waynezim.com/2014/03/powershell-file-sharing-permissions-report/
PowerShell Tips
ファイル名の一部を一括置換。
Get-Childitem | Foreach-Object {Rename-Item $_ ($_ -replace "mae", "ato") }
エラー処理は大事
PowerShellで「初期処理でループしながらファイルの削除とかやって、そのあとメイン処理に入ろう」なんてときに「コマンドレット実行結果NGでも空回って進んで欲しい!」って思うことありますよね。
Shellなので、コマンドのリターンコード見て条件分岐する、という発想でよいのですが、せっかくのPowerShellだし例外処理で実装してみよう、と思うわけです。ところが普通に書くとなかなかcatch節に入ってくれないです。
これは、デフォルトの$ErrorActionPreference(デバッグモード変数みたいなもん)の値が"Continue"であり、この時、「Write-Errorコマンドレットからエラー表示される処理はcatch節で補足されない」という仕様にヒットしているせいっぽいです。Remove-Itemがファイル削除に失敗してIOExceptionを投げる時、Write-Errorを使ってるのですね。
コマンドレットごとに、エラー時の動作を制御する引数として"-ErrorAction"というのが用意されていて、それを使って実行したコマンドレットについては$ErrorActionPreferenceの値をオーバーライドできます。
こいつを使って"Stop"にオーバーライドしてあげると、try/catchできるようになります。
試しに"hoge.txt"を作り、ロックを取得できるエディタ等で開いた状態で削除してみましょう。
New-Item hoge.txt -type file #ここでファイルを開いてロック
try{ Remove-Item hoge.txt }catch{ Write-Output "ナイスキャッチ" } # 削除を試みる
Remove-Item : 項目 E:\tmp\test\hoge.txt を削除できません: 別のプロセスで使用されているため、プロセスはファイル 'E:\tmp\test\hoge.txt' にアクセスできません。
発生場所 行:1 文字:17
+ try{ Remove-Item <<<< "hoge.txt" }catch{ Write-Output "ナイスキャッチ" }
+ CategoryInfo : WriteError: (E:\tmp\test\hoge.txt:FileInfo) [Remove-Item]、IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
ぬふう。
それでは、ErrorActionを指定してみる。
New-Item hoge.txt -type file #ここでファイルを開いてロック
try{ Remove-Item hoge.txt -ErrorAction:Stop }catch{ Write-Output "ナイスキャッチ" } # 削除を試みる
ナイスキャッチ
catch節に入った。
マニュアルは以下のコマンドから。
Get-Help about_CommonParameters
パケットを解析するときのメモ(おもにwiresharkを想定)
※以下、メモ書き途中につき参考程度とすること※
取得時
- 取得パケットサイズを途中で切るようにする(150kくらい?)
- データが大きくなる場合は以下を考慮
- ファイルを分割する(大きくても100MBくらいにしておいたほうがあとで調査が楽)
- キャプチャ時、画面を自動スクロールさせない
解析時
- 時刻表示は"Time of Day"など、時刻表示にしておく(主に他システムlogとの突き合わせのため)
- TCPの場合、パケットリストパネルに以下を表示する
- Windowサイズ
- Seq番号
- Ack番号
- Length(Ethernet)
留意点
- シーケンス番号は相対値。実値を表示したい場合はPreferenceのProtocolのTCPから表示を変更する。
- 通常表示されてるLengthはフレームサイズなので(=TCPセグメントサイズじゃない)、Seq番号計算するにはちゃんとセグメントサイズを見る必要がある。
おまけ
.zshrcの設定について
ついでに.zshrcの設定もメモろう。
参考にしたのはこちらのサイト。ちゅーか導入したばかりでお試し中につき、丸パクリ状態・・・
# Lines configured by zsh-newuser-install HISTFILE=~/.histfile HISTSIZE=20000 SAVEHIST=20000 bindkey -e # End of lines configured by zsh-newuser-install # The following lines were added by compinstall zstyle :compinstall filename '/home/bounoki/.zshrc' autoload -Uz compinit compinit # End of lines added by compinstall setopt ignore_eof zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' autoload -U colors ; colors PROMPT="%{$fg[green]%}%m@%n[%h]%#%{$reset_color%} " RPROMPT="%{$fg[green]%}[%(5~,%-2~/.../%2~,%~)]${WINDOW:+"[$WINDOW]"}%{$reset_color%}" preexec () { if [[ "$TERM" == "screen" ]]; then local CMD=${1[(wr)^(*=*|sudo|-*)]} echo -ne "\ek$CMD\e\\" fi }
.screenrcの設定
自宅PCの.screenrcの設定をメモっておこう。参考にしたサイトは忘れてしまいました。
escape ^Zz defscrollback 20000 hardstatus alwayslastline hardstatus string "%{.Wg}.: %-w%{.RW}%n %t@%H %{-}%+w :. %=[%Y-%m-%d(%D)]"
PowerShellで「デスクトップ」とか「マイドキュメント」のパスを調べる
Windowsでプログラムを書いてて、「デスクトップのパスが取得したい!」とか思うときありますよね。
Google先生に聞いてみると「%USERPROFILE%\デスクトップで取得可能だよ!」とか言われてしまい、駄目だこいつ・・・はやくなんとかしないと・・・状態になります。ご存知の通り、エクスプローラで"場所"を"移動"している場合Google先生案は役に立たないのです。
そういう時、新米Windowsエンジニアの僕にはすでに次の発想に至る用意があります。つまり、「レジストリを探せ」です。
Windowsの設定、情報の永続化の多くは「レジストリ」にレジスターすることにより実現されています。例えば、ユーザごとの設定であればHKLU、端末ごとの設定であればHKCUといった具合です(例外もあるよ)。
今回の対象は、"HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"にあるみたいです。
以下のスクリプトで取得できます。
# デスクトップとかマイドキュメントのパスが格納されているレジストリ $shell_folders_path="HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" # 値はプロパティとして保持されているらしいので、Get-ItemPropertyで取り出す $items = Get-ItemProperty $shell_folders_path # 試しにいくつか取得してみる。 $props_to_show = @( "DeskTop" ; "Personal" ; "My Pictures" ; "History" ; "Cookies" ) $props_to_show | Foreach-Object { Write-Output ( $_ + "はこれ→" + $items.$_ ) } # 全部出力する $items
上記の通りです。実行してみると以下のように出力されます(自分はデータは大体Eドライブに入れてます)。
DeskTopはこれ→E:\<ユーザ名>\Desktop Personalはこれ→E:\<ユーザ名>\Documents My Picturesはこれ→E:\<ユーザ名>\Pictures Historyはこれ→C:\Users\<ユーザ名>\AppData\Local\Microsoft\Windows\History Cookiesはこれ→C:\Users\<ユーザ名>\AppData\Roaming\Microsoft\Windows\Cookies …($items全出力は割愛)
これ書いてて気づいたんですが、マイドキュメントは「Personal」っていうプロパティみたいです。