禁じ手

そろそろWindowsXPからの脱出にブーストがかかってきていると思うので。

いろいろ思うところがあるので淡々と事実を書いていきます。(思うところ、はまた後日。)

状況

  • 業務システムはオトナの事情でXP仕様。トラブル発生時にリスクを考慮して重要度が高いものはXPを残留させて囲い込み。個々人が利用するマシンはWin7へ変更。
  • それでも個々人のマシンにインスコしなければならないシステム多数。もちろんフリーウェアでの代用等が出来ない代物。
  • リース期限等の問題で対策前進のみ。

同僚が死ぬ思いで入れ替えを進めています。おっちゃんは後方支援です。

で、決死の突撃隊と化した同僚がなんとかWin7へ入れ替えを完了させた後日、問題が発覚します。Officeアプリケーションが不安定に再起動を繰り返し、とうとう起動すらできない状態へ。ブルースクリーンでないのが幸いか。

どちらにせよどうしょもないので入れ替えたばかりの新マシンからさらに別のマシンへお引越しε≡≡ヘ( ´Д`)ノ

当初初期不良とも考えたが類似不具合を発見。法人向けPCの故障率としては異常です。

調べてみると各種Windowsサービスがぼろぼろ。権限がない、ファイルが開けない、見つからないといって起動できないサービス多数。ログすら吐けず沈黙のまま死んで原因不明の不具合を多発する状況。よくよく聞いてみればXPマシンから載せ替えた非対応アプリケーションのためにsystem32配下にPowerUserで権限を付けたとのこと。

なるほど。system32から配下へすべてPowerUserで権限を継承させたわけです。
おそらくその時、固有のサービスアカウントの権限がはがされてしまったのでしょう。

考えられる対処はOSのクリーンインストールですが、データ量が多い、業務が止められない等あるため、それは無理。(というか同僚が死にかけながらやった仕事をもう一回、ってことです。色んな意味で無理です)

よって現状を維持したままシステムアカウントの権限を復旧させるというアホみたいな作業をする羽目に。

無論system32以下の権限を各ファイルごと、サービスアカウントの権限を手作業でつけるなんてありえないので、ここはPowerShellを使います。

まず、system32以下のファイルと権限を取得します。

$fileObj = Get-ChildItem C:\Windows\system32 -Recurse Out-File C:\Users\administrator\Documents\sysroot_permission.csv -encoding utf8
foreach($file in $fileObj){
  $acl = Get-Acl $file.FullName
    foreach ($aclObj in $acl.Access){
      """" + $file.FullName + """,""" + $aclObj.identityReference.value + """,""" + $aclObj.FileSystemRights + """,""" + $aclObj.AccessControlType + """" | Format-List | Out-File -Append C:\Users\administrator\Documents\sysroot_permission.csv -encoding utf8
    }
  }

これでsystem32以下のファイル名と権限がリスト化されます。正常なマシンとエラーが出ているマシンの両方で結果を取得します。
そしたらexcelを使って付け合せ。Vlookupとかおなじみのアレで頑張ります。
差分が発生しているファイル、権限について「NT FOO\hoge」とか「BUILTIN\hoge」となっているものを中心に抜き出して、以下のコマンドを自力生成します。
ファイル名(フォルダ名)はCSVに吐き出した対象のファイル(ディレクトリ)、アカウント、権限です。CSVに吐き出したものをそのまま使います。

if([System.IO.File]::Exists("C:\Windows\system32\1033")){
  $acl = Get-Acl "C:\Windows\system32\1033"
  $aclparam = @("BUILTIN\Administrators","FullControl","Allow")
  $rule = New-Object  System.Security.AccessControl.FileSystemAccessRule  $aclparam
  $acl.AddAccessRule($rule)
  Set-Acl "C:\Windows\system32\1033" -AclObject $acl }

まあ、パッチ用スクリプトなんかをよく作る人は慣れているかもしれませんが、最初にリスト化してexcelでグリッドに載せているので列追加で固定記述を足し、適当に改行用フラグを挟みながらグリッド上で整形、テキストエディタでタブ消しと改行フラグを改行コードに変換すればすぐ大量生産できます。

ちなみにif文を混ぜてファイル存在チェックをかましているのは各マシンでインストールされてるアプリケーションが違ったりClassIDを振られたものは一致しないからです。
もうそこはサービス起動しながらコケたら手で直すしかありません。

で、結果修正(?)スクリプトだけで6MBという化け物が出来上がり、そいつを実行して、再起動。これでやっと治りました。

本当にレガシーシステムを延命しようとする人たちは不毛なトラブルを連れてきます。
もちろん、改修しないために浮いたお金もあるんでしょうが・・・・。
おいちゃんは生産しない人なのでおいちゃんの手間は無価値と考えても、引っ越し作業で業務が止まっていた人、原因不明のエラーに頭を抱えた情報システムの人、そういう見えないコストを考えると「浮いたお金」は浮きっぱなしのまま波間に消えてるんじゃないかなーというのが本音です。

まあ、個人的にはWindows環境の権限周りを掘り下げて勉強できたので収穫はなにもなかったわけじゃないかな?(ポジティブシンキング!!)
あれ?そう考えると「浮いたお金」はおいちゃんの勉強代に消えたのかも・・・?

人生万事塞翁が馬!おいちゃん、得したよ!ポジティブシンキング大事!

補足:

中には一括である特定の権限だけ足したいケースもあるかと思います。
今回のようにPowerUserを今ある権限に追加したい、、、、とかね。
その場合はこちら。

$aclparam = @("DMAIN\権限欲しいユーザ", "Fullcontrol", "Allow")
$rule = New-Object  System.Security.AccessControl.FileSystemAccessRule  $aclparam
$fileObj = Get-ChildItem C:\windows\system32 -Recurse
foreach ($file in $fileObj){
  if(!$file.PsIsContainer){
    $acl = Get-Acl $file.FullName
    $acl.AddAccessRule($rule)
    Set-Acl $file.FullName -AclObject $acl
  }
}

これはある特定のフォルダを指定し、その配下のファイルにすべて同じアカウントでフルコントロール権限を追加するスクリプトです。
おいちゃんの例でいうと、最初の時にこうやって「継承」ではなく「追加」でこなしていれば問題は発生しなかったことになります。
まあ、それも失敗したからこそわかったことです。
失敗は秘伝のたれのもと!

広告
カテゴリー: お仕事 タグ: , パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中