ラベル Powershell の投稿を表示しています。 すべての投稿を表示
ラベル Powershell の投稿を表示しています。 すべての投稿を表示

2019/11/12

Microsoft TeamsをPowerShellを使って動的更新グループとして一括作成したい



というわけで、PowerShellで チームを一括作成できるか
調査してみました。

まず、Microsoft TeamsはOffice365グループと連動しています。
さらに、Office365グループを動的メンバーシップにすることで
Teams側でも動的更新できるみたいです。
チームの動的なメンバーシップの概要 - Microsoft Docs
https://docs.microsoft.com/ja-jp/microsoftteams/dynamic-memberships

2016/12/06

PsExecを使用したクライアント一括設定 その1

この記事は SRA Advent Calendar 2016 参加記事です。


■PsExecを使ってリモートから一括設定をする

PsExecはマイクロソフトが提供するリモートからコマンド実行するツールです。
以下のサイトよりダウンロード、使い方を確認することができます。

TechNet PsExec

より詳しい説明は、@ITの記事がわかりやすいです。
@IT PsExecを使ってリモートのWindows PC上のプログラムを実行する


今回、Windows10の大量展開作業をする機会があり、
イメージ展開後、ホスト名とドメイン変更、各種設定をPsExecコマンドを使って
一括で変更しました。

その時に使ったコマンドと流れを少し紹介したいと思います。


2012/11/15

PowerCLIをいじってみた


VMWareを動作させるにあたって、コマンドベースで動かすことが可能なPowerCLI。
PowerShellでの動作というのがなんともありがたい。
ということで、とりあえず入れて動かしてみました。
とりあえず、以下のサイトを参考にしつつインストール。

Think IT 第4回 PowerCLIを使った仮想化の自動運用
http://thinkit.co.jp/story/2011/02/24/2008

VMware vSphere PowerCLI 5.1 ダウンロード
https://my.vmware.com/jp/web/vmware/details?downloadGroup=VSP510-PCLI-510&productId=28

インストールしてできたPowerCLIのショートカットを叩いてもよいですが、
普通にPowerShellからSnapinを追加しても良いです。

Add-PSSnapin vmware.vimautomation.core
Get-PSSnapin vmware.vimautomation.core
image

読み込まれました。


2012/11/04

ログをメーターとして表示させるPowerShellスクリプト


ってことで、下のようなsample.txtがあったとして・・

こんな感じで出力させます。

というわけで以下、ソース

2011/12/18

れあつい ~Twitterフォローユーザーのレア発言を取得してみる~

(* この記事は PowerShell Advent Calendar 2011 18日目の参加記事です。)


raretwit.ps1というスクリプトを作りました。
コードは一番下に置いたので、すぐに使ってみたいひとはそちらをどぞ。

2011/09/09

長月3.プログラムの実行回数を出力させる仕組みをみてみる3

前回の続きです。

長月1.プログラムの実行回数を出力させる仕組みをみてみる
http://win-enikki.blogspot.com/2011/09/1.html
長月2.プログラムの実行回数を出力させる仕組みをみてみる2
http://win-enikki.blogspot.com/2011/09/1_05.html

前回、最後にスクリプト付け加えました。
これは最終実行時間と、できたデータをオブジェクトに入れる処理です。

#レジストリプロパティを入力、時間を出力
function convtime($x) {
    $LittleEndianTime=$x[60..67] | % { $_.tostring("x2") }
    $BigEndianTime=$null
    $($LittleEndianTime.count-1)..0 | % { $BigEndianTime += $LittleEndianTime[$_] }
 
    $filetime=[convert]::ToInt64("$BigEndianTime", 16)
    [datetime]::fromfiletime($filetime)
}
 
#オブジェクトに各データを入れデータ格納
$result = $iname | % {
    $count = $iProp.$_[4]
    if ($count -ne 0){
        $output = New-Object psobject
        $output | Add-Member noteproperty pcount $iProp.$_[4]
        $output | Add-Member noteproperty pname $(func $_)
        $output | Add-Member noteproperty ptime $(convtime $iprop.$_)
        $output      
    }
}
 
#お好みでオブジェクト整形
$result | sort-Object -Property ptime -Descending

この処理はだいたい以下のような動きをさせている

2011/09/05

長月2.プログラムの実行回数を出力させる仕組みをみてみる2

前回の続き

長月1.プログラムの実行回数を出力させる仕組みをみてみる
http://win-enikki.blogspot.com/2011/09/1.html

では、残りのスクリプトをみていきます。

$iName | %{
    $count = $iProp.$_[4]
   
    if ($count -ne 0){
        "{0}回 {1}" -f $count, (func $_)
    }
}

プログラム名が記述されている$iName、
そのプログラムの実行回数を含む各種データが格納されてある$ipropを利用して、回数を表示させる。

では、そもそも$ipropに書かれているデータ構造はどうなっているのだろう?
$iPropに格納されているのは、以下のレジストリキーをカスタムオブジェクトとして取得し、
データを各プロパティ値として取得している。
HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\Count

レジストリエディターでキーをみたところ

2011/09/01

長月1.プログラムの実行回数を出力させる仕組みをみてみる

とっても面白いPowerShellスクリプトが掲載されていたので ご紹介

のんべんだらりぃ~ プログラム実行回数
http://d.hatena.ne.jp/chiaki1220jp/20110831

Windowsのレジストリにはプログラムの実行回数が記録されているところがあるので、
それを利用してどのプログラムを何回実行したかというのを出力するというもの。
一時、Winny防止の為 本当に起動してないかどうかを確かめるためのソフトが話題になったけど
そのソフトもどうやらここのレジストリを見ているみたい。
とはいえ、プロファイルに記載されるレジストリ値であり、 ユーザーによっていくらでも書き換えができてしまうので、
どちらかといえば 使用頻度とかをリサーチする 統計的な目的で利用するのが正しいのかな。

実際に実行してみたところ。回数とプログラムが出力される
では、動作をひとつずつ見ていくことにする。

2011/08/30

葉月1.PowerShellのプロファイルとSyncToyを利用したバックアップ

僕が使っているのは、MSが出しているSyncToyというツール。
これを利用するとフォルダ間でファイル同期を行ってくれる。手軽に使えるのでなかなか良い

SyncToy

@IT SyncToyツールで手軽にバックアップを行う

コマンドプロンプトでも実行できるので、USBメモリをさした場合にプロファイルを読み込み、
その過程で上記ソフトを実行するよう設定する。

2011/03/27

東京電力電力供給状況APIを使ってPowerShellからデータ出力

久々の投稿です。しばらくPowerShellを扱ってなかったので、リハビリ。

関東では現在計画停電が行われていますが、
有志にて東京電力の電力使用状況APIを公開している方がいます。

東京電力の電気使用状況 API
http://denki.cuppat.net/

これを利用して二日分の電力データをPowerShellにて出力してみます。
Function Get-Data {
    Param($date)
    if ($WebClient -eq $null) {
        $Global:WebClient=new-object System.Net.WebClient
    }
    $results=$webClient.DownloadString("http://denki.cuppat.net/data/$($date).json")
    $Results -match """hours"":\[(?<hour>.*)].*""capability""\:(?<cap>.*)," > $null
    $matches
}

Function Check-Data {
    Param($getdata)

    $Ltime = $getdata.hour -split ","
    $cap=$getdata.cap
    write-host キャパシティ $cap

    0..$(($Ltime.length)-1)|% {

        $p=$ltime[$_]/$cap

        if ($p -ge 0.95) {
            $colorname="red"
        }elseif ($p -ge 0.90) {
           $colorname="darkyellow"
        }else {
            $colorname="black"
        }
       

        $a="{0:00}時:電力{1} {2:00}% {3}{4}|" -F $_,$ltime[$_],$($p*100),$("#"*$($p*50)),$(" "*(50-$($p*50)))
        write-host $a -ForegroundColor $colorname
        }
}

$tdata=Get-Data($(get-date -uformat "%Y%m%d"))
$ydata=Get-Data($(get-date -uformat "%Y%m%d")-1)

check-data($ydata)
check-data($tdata)

実行した結果はこちら。
90%以上の利用率で黄色、95%以上で赤字で出力します。

こうみると、やはり夕方は電力量が上がってますね。
僕も引き続き、節電していきたいと思います。

2010/12/20

PowerShellでTwitter


ということでPowerShellを使って Twitterチェックスクリプトを作っているのだけど
自分のやりたい挙動の八割はできたー。
こうやってTwitterを眺めているとなかなか面白い。
少しずつ作成した箇所を紹介できればいいなぁと思います。

とりあえず、こちら。
Twitter API の仕様書 日本語訳
http://watcher.moe-nifty.com/memo/docs/twitterAPI.txt

あと、TwitterAPI searchについてはこちらも参考になりました。

Twitter Search API の使い方
http://www.ibm.com/developerworks/jp/xml/library/x-twitsrchapi/

なにはともあれ、Twitter Search APIを使って情報をとってみる。
Function Get-TwitterSearch {

 Param($searchTerm)

 if ($WebClient -eq $null) {
  $Global:WebClient=new-object System.Net.WebClient
 }

 $results=[xml]($webClient.DownloadString("http://search.twitter.com/search.atom?lang=ja&q=$SearchTerm"))
 $Searchitems=$results.feed.entry

 $SearchItems
}

Get-TwitterSearch関数をつくって、引数に検索する文字を入れることで、
Twitter情報をxml形式でひっぱって返してくれます。

検索の仕様だとかは上記の参考リンクを参照してもらうとして・・。
データをとれればしめたもの。あとはいくらでもPowerShellで編集できちゃいます。
とりあえず、名前と時間、つぶやきを取得したいのであればこんな感じ。
PowerShellをつぶやいた人をとってみました。

$tdata= Get-TwitterSearch PowerShell
$tdata | %{ write-host $_.author.name "--" $([datetime]$_.published); write-host $_.title; write-host }


あとはこれを応用すれば 
好きなキーワードをストリーミングでずっと流し続けることができると。
任意のユーザーに対しても検索できるので、その紹介はまた機会あらば。

2010/11/15

ログの書き込みがあったら知らせるスクリプト

前回の続き。
http://win-enikki.blogspot.com/2010/11/usbpowershell.html

前回はUSBメモリ使用者にログオフ時にメッセージ出力するスクリプトを紹介しました。
今回は、出力ログを監視することで監視者に知らせるスクリプトを紹介します。
とりあえず、スクリプト例を以下に表示します。
$writeDir="\\buso-pcv\test"
$writeTxt="usblog.txt"
$tmpColor= @("Red", "Blue", "Green", "Magenta", "DarkCyan")

[Void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$i = 0 #終了フラグ
$cl = 0 #カラーバリエーション
$watcher = New-Object System.IO.FileSystemWatcher              # FileSystemWatcherの作成
$watcher.Path = $writeDir                                      # 監視対象のフォルダ指定
$watcher.Filter = $writeTxt                                        # フィルター
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite 

$NotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$powerShellExe = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($powerShellExe)
$notifyIcon.Icon = $icon
$notifyIcon.Visible = $true

Write-Host "チェック開始します。"

while ($i -ge 0)
{
    $result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::ALL)
    $tmpVar = $(Get-Content "$writeDir\$writeTxt")[-1] -split ","
    
    Write-Host ""
    Write-Host "#########################################"
    Write-host "【コンピュータ】"  $tmpVar[0] -ForegroundColor $tmpColor[$cl]
    Write-host "【ユーザー】"  $tmpVar[1] -ForegroundColor $tmpColor[$cl]
    Write-host "【ログオフ時刻】"  $tmpVar[2] -ForegroundColor $tmpColor[$cl]
    Write-Host "#########################################"
    
    $notifyIcon.ShowBalloonTip("1", "USBチェック", "USBメモリがささっているユーザーがいます", "Info")

    $cl+=1
    if ($cl -eq $tmpColor.length) {
        $cl=0
    }
}

ここでのポイントはFileSystemWatcher クラスです。
FileSystemWatcher クラス
http://msdn.microsoft.com/ja-jp/library/system.io.filesystemwatcher%28VS.80%29.aspx

監視ログを対象に、書き込みが発生したらログの最終行を出力させる。
また、ログは変更した場合分かりやすいようtmpColorにある配列順に文字色を代えるようにしています。
ついでに、NotifyIconクラスを使用してバルーン表示もさせています。
NotifyIconクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.notifyicon%28VS.80%29.aspx

以上の結果でこのように表示されます。
出力ごとに色が変わり、バルーンも出力



















このスクリプトは、今回だけでなく他でもログに書き込みがあった場合の監視ができるので、
色々汎用性が高いかなーとおもってます。
いかがでしょうかー。

2010/11/10

USBメモリ抜き忘れ防止スクリプトをPowerShellでやってみる

久々にPowerShellを使う機会にめぐまれたので、投稿します。

USBメモリ、今では安価となりかなり利用率は増えましたが
それと同時にメモリの抜き忘れも増えているみたいです。
なんとかならんのかー、という要望があったので
折角なのでPowerShellでログオフ時にUSBメモリがささっているとダイアログを出すスクリプトを作ってみました。
ちなみに、色々ネット上にある参考スクリプトをツギハギしたりしています。
使用時は自己責任でお願いします ><


とりあえず、1つ目のポイントとして、USBメモリの有無確認ですが、
win32_usbhub クラスを利用することでみつけることができます。

Win32_USBHub クラス - WMI Fun !!
http://www.wmifun.net/library/win32_usbhub.html

USBメモリの場合、Nameが "USB 大容量記憶装置"であり、
Statusが"OK"であれば、ほぼちゃんと認識された状態のUSBメモリがささっているといえます。
Get-WmiObject -Class win32_usbhub | ? { $_.name -eq "USB 大容量記憶装置" } | ? { $_.status -eq  "OK" }
USBメモリをさしていた場合

あとは、ダイアログとして出すようにスクリプトを組めば完成です。
詳細は以下。
#USBログオフ時メッセージプロンプト処理
#メッセージ文
$messagePath="C:\temp\usbmessage.txt"
#ログ出力パス
$usbLOG="\\buso-pcv\test\usblog.txt"

#--------------------------------------
#メッセージボックス
#--------------------------------------
function MessageBox([string]$p_value = "")
{
    [Void][Windows.Forms.MessageBox]::Show($p_value,"お知らせ","OK", "Warning")
}


$crUSB = Get-WmiObject -Class win32_usbhub | ? { $_.name -eq "USB 大容量記憶装置" } | ? { $_.status -eq  "OK" }


if ($crUSB) {
    write-output "$env:computername,$env:username,$(get-date)" >> $usbLOG

    #Windowsフォームのロード
    [Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");

    MessageBox $([String]::Join("`r`n", (Get-Content $messagePath)))
   
}
 メッセージ文は、いろんな人が編集する場所でもあることから、
別テキストからの呼び出しに 。(ここでは "C:\temp\usbmessage.txt")
以下のようにusbmessage.txtに書いてみました。
USBがさしっぱなしだぞー( ゚Д゚)
誰かに盗まれても知らないぞ( ´∀`)
って、席にもういないッッΣΣ(゚Д゚;)
また、ダイヤログが出たときに、使用者のホスト名、ユーザー名、時刻を吐き出すようにしてみました。
このスクリプトをログオフスクリプトとして設置しておけば完了です。
実際に使用するとこんな感じ。
USB差しっぱなしでログオフした場合

usblogに記録されたログ

ちなみにGPOでPowershellのログオフスクリプトを管理する場合には、
スクリプト実行ポリシーを有効にすることと、PowerShell用のタブが別途あるので注意しましょう。
(あと、もちろん適用環境ではPowerShellがインストールされていることが前提です(笑))


GPOによるスクリプト実行ポリシーの許可

ログオフスクリプトのPowerShellタブ

また、「ハードウェアの安全な取り外し」を行わなくても大丈夫か?という点については
書き込み中でなければ、ほぼ問題ないとのこと。
ログオフ後なら なおのこと その後ぬいても問題ないでしょう。
どうしても怖いというのであれば、もう一度ログインして手順を踏んで抜いてもらうということで。

USBメモリやUSB HDDを安心して取り外す - ITmedia
http://bizmakoto.jp/bizid/articles/0710/03/news062.html


さて、これで使用者には注意を促しましたが、上記のメッセージにある通り
そもそも、使用者はログオフボタンを押した時点で皆 律儀に席に座っているとはかぎりません。

なので、USBメモリをさしてログオフした人を管理者へ知らせるスクリプトも作ってみました。

今回は長くなったので、スクリプトについてはまた次回。
ちなみに動作としてはこんな感じに出力させました。
USBメモリさし忘れ監視
ログを監視し続けて、書き込みがあったら出力、ついでにポップアップ表示もさせています。
では、また次回。(といって、またえらく時間あいたら嫌だな・・)

2010/06/04

PowerShellにしゃべらせる

Windowsでしゃべらせるには色々な方法があるみたいですが、
.NET Framework 3.0 を入れているのであれば、Speech.Synthesis.SpeechSynthesizerクラスを使うのが楽っぽいです。
$null = [Reflection.Assembly]::LoadWithPartialName("System.Speech")
$SMSpeaker = new-object System.Speech.Synthesis.SpeechSynthesizer

あとは Speakメソッドでしゃべらせるだけ。
 $SMSpeaker.Speak("hello buso")
日本語はデフォでは対応していないらしく、Office2003についてくるLH Kenj なんかの音声合成エンジンを使わなければならないっぽい。
2010も出る今となってOffice2003といわれてもなぁ。
ちなみに、ツイッターと連動させて読み上げさせるスクリプトを作っている人もいました。
うーん、僕も日本語でも読み上げさせたいぞ。


まぁ、監視として、何かあったら読み上げるというのもこれで簡単にできそうですね。

2010/06/01

サーバのグループポリシーのリンク監視の方法を模索してみる その3

さらにグループポリシーリンク監視の模索の続き。
サーバのグループポリシーのリンク監視の方法を模索してみる その1
サーバのグループポリシーのリンク監視の方法を模索してみる その2

前回、前々回とポリシー編集とリンクの付与の比較を出力する方法を模索し、
スクリプトを作ってみました。処理内容はこんな感じ。


エラー時の動作などはまったく組み込んでないので参考程度でどぞ。
#CheckGPO

Import-Module activedirectory
Import-Module grouppolicy

#origpoファイルの場所
$workpath="C:\hogehoge\"

#メール配信先設定
$smtpHost = "SMTPサーバアドレス"
$mailfrom = "FROMのアドレス"
$mailto = "メール配信先"
$mailsubject = "GPOCheckログ"
$mailer = New-Object System.net.mail.smtpclient($smtpHost)

function comparegpo ($crlink, $orilink, $crgpo, $origpo) {
    
#gpo設定 変更された場合は新しいGPOのバックアップを行い oriファイルを更新
    compare-object $crgpo $origpo -property modificationtime,gpostatus,displayname | Set-Variable diffgpo
    if ($diffgpo) { 
        "$(get-date) :--GPO変更が発生しました"
        $diffgpo | sort displayname | ft -AutoSize
    $timename=$(Get-ItemProperty $workpath\origpo.xml).LastWriteTime -replace "[/,:, ]",""

    $diffgpo | ? { $_.sideindicator -eq "<=" } | % { "backup実施"; backup-gpo $_.displayname -path $workpath\gpbackup | fl }
    move-item $workpath\origpo.xml $workpath\log\$timename"gpo.xml" | Out-null
        $crgpo | Export-Clixml $workpath\origpo.xml
     }

#link設定  変更された場合は oriファイルを更新
    compare-object $crlink $orilink -Property target,displayname,enabled | Set-Variable diffgpl
    if ($diffgpl) { 
        "$(get-date) :--GPO Linkに増減が発生しました"
        $diffgpl | sort displayname | ft -AutoSize
    $timename=$(Get-ItemProperty $workpath\orilink.xml).LastWriteTime -replace "[/,:, ]",""
    move-item $workpath\orilink.xml $workpath\log\$timename"orilink.xml"
        $crlink | Export-Clixml $workpath\orilink.xml 
    }

}

#origpo存在チェック
if (test-path "$workpath\origpo.xml"){
    $origpo=Import-Clixml "$workpath\origpo.xml"
} else {
    "origpo.xml NotFound"
    get-gpo -all | Export-Clixml $workpath\origpo.xml
    return
}

if (test-path "$workpath\orilink.xml"){
    $orilink=Import-Clixml "$workpath\orilink.xml"
} else {
    "orilink.xml NotFound"
    Get-ADOrganizationalUnit -Filter 'Name -like "*"' | % { Get-GPInheritance -Target $_ } | ? { $_.gpolinks -ne "" } | % { $_.path; $_.gpolinks } | Export-Clixml $workpath\orilink.xml
    return
}


#現在のOU状態の取得
$crlink = Get-ADOrganizationalUnit -Filter 'Name -like "*"' | % { Get-GPInheritance -Target $_ } | ? { $_.gpolinks -ne "" } | % { $_.path; $_.gpolinks }
$crgpo = get-gpo -all


#比較対象を関数で渡し、戻り値が存在した場合にはメールを出す
$result=comparegpo $crlink $orilink $crgpo $origpo

if ($result) { 
    $mailbody=[string]::join("`r`n", ($result | out-string -width 200 ))
    $mailer.send($mailfrom, $mailto, $mailsubject, $mailbody )
    $result | out-string -width 200 > $workpath\recent.log
    $result
    "変更が発生し、メールを出しました"
}
$work フォルダの配下にlog フォルダと、 gpbackupフォルダを用意してください。
適当にGPOを変更かけて、リンクをつけたあとにスクリプトを実行してみました。


あとはこのスクリプトを一定時間のタスクで回しておけば、
多少の監視にはなるかなぁと。

結局、サイトのGPOは対応できなかったけどなッッ

2010/05/24

サーバのグループポリシーのリンク監視の方法を模索してみる その2

前回の続き
前回は、OUのリストを取得し、そこに貼られているGPOを出力するということをやりました。
で、OUに貼られているGPOはとれてもサイトに貼られたGPOはとれないね、というところまでやりました。

・・・まぁ、サイトに関するGPOはとりあえずおいとく(笑)
できるところを固め、そこから順次付け足すというのが 僕の今ままでの手法なので
とりあえずできそうなところからやってみます。
ということで、オリジナルGPOと変更したGPOを比較する手法を今回はやってみます。


前回はリンクに関することしか触れませんでしたが、
PowerShell v2 のgrouppolicy モジュールにはGet-GPO というGPO情報を取得できるコマンドがあります。

PS > Import-Module grouppolicy
PS > get-gpo -all

 -All オプションをつけることで、すべてのGPOの情報を取得できます。
情報としては、Statusや、変更時刻などが記されているので、この情報を保存します。
PowerShellだとオブジェクトはXMLファイルとして保存できるので、それを利用してみます。
PS > Get-GPO -All | Export-Clixml -Path .\origpo.xml
では、試しにGPOを変更して、比較してみましょう。
↓が現在のGPO

GPOtest1を内容変更、GPOtest2を「すべての状態を無効」 GPOtest4を削除してみます。

では、さっき保存したorigpo.xml と現在のGPOを比較してみます。
PS > $origpo=Import-Clixml .\origpo.xml
PS > $crgpo=Get-GPO -All

PS > Compare-Object $crgpo $origpo -Property displayname,modificationtime,GpoStatus | sort displayname


表示名、変更時刻、ステータスを比較対象として出力してみました。
ちゃんと、変更された、削除されたGPOが出力されていますねー。
これを定期的に実行、タスクに組み込むことで変更に対する監視ができるのではないでしょうか。
前回のOUリンクも同じ方法でオブジェクトを保存し、リンクの比較をしてみるとよいかもですね。

・・でも、サイトのやりかたはやっぱりわからんw

2010/05/19

サーバのグループポリシーのリンク監視の方法を模索してみる


さて、久々の更新です。
独りよがりで描かず、今後は定義を再確認しつつ
わかりやすく絵で表現していこうかなーと思っていたのですが、
少し作ってみたいPowerShellのスクリプトができたので、
やっぱり今回もPowerShellのメモ描きですw

その作ってみたいスクリプトとは・・


他に良い案があればみなさんに教えてもらうとして・・(笑)
とりあえず、泥臭い手段でPowerShellを使って模索してみます。

PowerShell v2 になってからADに関するモジュールが追加されたので、それを利用してみましょう。
とりあえず、ActiveDirectory と、GroupPolicy のモジュールを追加してみる。
PS > Import-Module activedirectory
PS > Import-Module grouppolicy
これにより、ADやグループポリシーに関するコマンドを使用することができます。
PS> Get-Command -module activedirectory


CommandType     Name                            Definition
-----------     ----                            ----------
Cmdlet          Add-ADComputerServiceAccount    Add-ADComputerServiceAccount...
Cmdlet          Add-ADDomainControllerPasswo... Add-ADDomainControllerPasswo...
Cmdlet          Add-ADFineGrainedPasswordPol... Add-ADFineGrainedPasswordPol...
Cmdlet          Add-ADGroupMember               Add-ADGroupMember [-Identity...
Cmdlet          Add-ADPrincipalGroupMembership  Add-ADPrincipalGroupMembersh...
PS > Get-Command -module grouppolicy


CommandType     Name                            Definition
-----------     ----                            ----------
Cmdlet          Backup-GPO                      Backup-GPO -Guid -Pat...
Cmdlet          Copy-GPO                        Copy-GPO -SourceGuid ...
Cmdlet          Get-GPInheritance               Get-GPInheritance [-Target] ...
Cmdlet          Get-GPO                         Get-GPO [-Guid] [[-Do...
Cmdlet          Get-GPOReport                   Get-GPOReport [-Guid] ...
 さて、では例として下記のようにGPOがリンクされていた場合。

GPOのリンクが何がついているかを見るには、 Get-GPInheritance コマンドレットを使います。
PS> Get-GPInheritance -target "OU=GroupA,OU=UserList,DC=furyu,DC=local"




Name                  : groupa
ContainerType         : OU
Path                  : ou=groupa,ou=userlist,dc=furyu,dc=local
GpoInheritanceBlocked : No
GpoLinks              : {GPOtest1, GPOtest2}
InheritedGpoLinks     : {GPOtest1, GPOtest2, Default Domain Policy}
 ちょっとこれだけだとわかりづらいから、 GpoLinks だけを取り出してみる。
PS > Get-GPInheritance -target "OU=GroupA,OU=UserList,DC=furyu,DC=local" | % { $_.gpolinks }


GpoId       : 09ecc96a-2d91-4594-8474-4404e82241d2
DisplayName : GPOtest1
Enabled     : True
Enforced    : False
Target      : ou=groupa,ou=userlist,dc=furyu,dc=local
Order       : 1


GpoId       : 72e4f0a0-7b01-4944-9fba-6ad14faefb49
DisplayName : GPOtest2
Enabled     : True
Enforced    : False
Target      : ou=groupa,ou=userlist,dc=furyu,dc=local
Order       : 2
これで、 OUが "OU=GroupA,OU=UserList,DC=furyu,DC=local" のかかっているリンクのGPOをとりだすことができました。
しかし、監視するとなると全OUのリンク状況を知らないといけないですよね。
というわけで、全OUを列挙してみましょう。
OUを出すには、ActiveDirectoryモジュールを追加してできた、Get-ADOrganizationalUnit コマンドレットを使います。
PS > Get-ADOrganizationalUnit -Filter 'Name -like "*"'


City                     :
Country                  :
DistinguishedName        : OU=Domain Controllers,DC=furyu,DC=local
LinkedGroupPolicyObjects : {CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=Polici
                           es,CN=System,DC=furyu,DC=local}
ManagedBy                :
Name                     : Domain Controllers
ObjectClass              : organizationalUnit
ObjectGUID               : ee6dfe99-a1f5-4579-b810-d12d22fcdfff
PostalCode               :
State                    :
StreetAddress            :
 これで全OUを取り出せるので、このオブジェクト群を変数にいれてしまいます。
PS > $oulist=Get-ADOrganizationalUnit -Filter 'Name -like "*"'
 では、この変数を利用してリンクが貼られているOUとそのGPOを出してみましょう。
PS > $oulist | % { Get-GPInheritance -target $_ } | ? { $_.gpolinks -ne "" } | fl -Property path,gpolinks


Path     : ou=domain controllers,dc=furyu,dc=local
GpoLinks : {Default Domain Controllers Policy}


Path     : ou=groupa,ou=userlist,dc=furyu,dc=local
GpoLinks : {GPOtest1, GPOtest2}


Path     : ou=groupb,ou=userlist,dc=furyu,dc=local
GpoLinks : {GPOtest2, GPOtest3, GPOtest1, GPOtest4}

あとは、このオリジナルのリストと、取得したリストを比較するスクリプトを定期的にタスクで流して差異がでたら報告、みたいな作りをさせればなぁと思ったのですが。


そんなわけで、もう少しやり方考えなきゃなぁと思ってます。

2010/04/04

タスクスケジューラ設定

4月1日、エイプリルフール。
円谷プロでは毎年手のこんだサイトを作りあげるが、
今年はTwitterの模倣、円谷ッターをやっていた。
円谷ッター(跡地)
http://tsubutter.m-78.jp/



ウルトラ兄弟と怪獣達が円谷ッターを使って、
4月1日終日ずーっとつぶやいていた。
0時から23時までほぼずっと誰かがつぶやいていたけれど、
流石に社員がずっと張り付いていたわけではあるまい。
(ゴモたんは別だろうけれどもw)

先週ツギハギで作ったTwitterスクリプトを利用しつつ、
Twitterのタスクスケジュールつぶやきができないかなぁと考えたが・・

簡単にできると思ったが、思った以上に苦労

まず、Windowsのタスク処理を見なければなるまい。
Vista,2008Serverからタスクスケジューラの機能が大きく変わった。
IT Prp: 大幅に強化されたWindows Server 2008のタスク・スケジューラ
フォルダを作成し、タスクを管理するライブラリ機能もつき管理しやすくなったようだ。


それを踏まえた上で、この記事を参照してみよう。
Hey, Scripting Guy!: タスク スケジューラを使って効率的に作業する方法はありますか
PowerShellを利用したタスク管理のスクリプトである。
上記のスクリプトを使って、「Twitter」ライブラリを作ってみる。




デフォルトのタスクスケジューラ
 . .\taskps.ps1
New-TaskFolder -folder (New-TaskObject) -path "\twitter"

Name                                                             Path
----                                                             ----
twitter                                                          \twitter

Twitterフォルダが作成された。

続いて、タスクの登録に関しては以下の記事。
Hey, Scripting Guy!: スケジュールされたタスクを複数のコンピューター上に作成する方法はありますか

と、上記を参考にしながら昨日ガシガシ作ったのだけど、
特殊なことをせず、素直にATコマンドを使えば良かったような気がする・・。
あらかじめ未来のつぶやきを設定して「おえかき うぃる」とつぶやきたかったのです。。
完成したにはしたけれど、ちょっと微妙な感じなので今回はコード公開は見送り。

2010/03/28

PowerShellでTwitter投稿

こんな記事を見た。

twitter で大学のネットワークを監視 [これでも大学職員のブログ -情報センター勤務中-]
http://d.hatena.ne.jp/daigaku-syokuin/20100326/p1

と、いうわけで探してみました。
やはりPowerShell経由でTwitter投稿するスクリプトを作っている方がいました。

SAPIEN Technologies
http://blog.sapien.com/index.php/2008/06/23/out-twitter/

Mike Ormond's Blog
http://blogs.msdn.com/mikeormond/archive/2009/01/30/updated-twitter-powershell-script.aspx

素晴らしい。で、二つのスクリプトの良いとこ取りをしてくっつけてみた。
以下をFixtwit.ps1 として保存してください。
Function Out-Twitter {

    BEGIN {
            #check for global Twitter credential
            if (!$global:Twitter_Credential) {
                $global:Twitter_Credential=Get-Credential
            }
    }

    PROCESS {
  
        #turn off error pipeline
        $erroractionpreference="SilentlyContinue"
  
        [string]$tweet=$_
  
        ##Twitter投稿関数
        function SubmitWebRequest(  
            [string] $RequestUrl,
            [string] $RequestMethod,
            [string] $RequestContentType,
            [string] $PostString,
            [string] $Username,
            [string] $Password
            )
        {
          [System.Net.ServicePointManager]::Expect100Continue = $false

          $request = [System.Net.WebRequest]::Create($RequestUrl)
          
          if ($Username) {
            $request.Credentials = new-object System.Net.NetworkCredential($Username, $Password)
          }
          
          $request.Method = $RequestMethod
        
          if ($RequestMethod -ieq "POST") {
            $request.ContentType = $RequestContentType      

            $formdata = [System.Text.Encoding]::UTF8.GetBytes($PostString)
            $request.ContentLength = $formdata.Length
            $requestStream = $request.GetRequestStream()
            $requestStream.Write($formdata, 0, $formdata.Length)
            $requestStream.Close()
          }
        
          $response = $request.GetResponse()

          $reader = new-object System.IO.StreamReader($response.GetResponseStream())
          $returnvalue = $reader.ReadToEnd()
          $reader.Close()
        
          return $returnvalue
        } #end function
      
        #Short Url
        Function Get-Snurl {
            Param([string]$link="http://www.google.com")
      
            $tinyurlrequest = "http://tinyurl.com/api-create.php?url=$link"
                       

            write-progress "Tweeting" "Getting tiny URL" -cu $tinyurlrequest
            $tinyurl = SubmitWebRequest $tinyurlrequest "GET"
            write-debug "Tweeting - Received tiny URL Response: $($tinyurl)"
            write $tinyurl
  
        }
        #search for web links using Regex
        [regex]$regex="(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?"
  
         If ($tweet -match $regex) {
                  $link=$matches[0]
          }
       
         #if an embedded url was found, convert it to a snurl link
         if ($link) {
            $snurl=Get-Snurl $link
            $tweet=$tweet.Replace($link,$snurl)
         }


        if ($tweet.Length -gt 140) {
            Write-Warning ("Your message is " + (($tweet.length)-140)  + " characters too long.")
            $clear=$True
            return
        }
      
      
        $tweetstring = [String]::Format("status={0}", $tweet)
        $request = [Net.WebRequest]::Create($url)
        $twitusername=$global:Twitter_Credential.GetNetworkCredential().Username
        $twitpassword=$global:Twitter_Credential.GetNetworkCredential().Password
      
        $twitResponseText = SubmitWebRequest `
                                    "http://twitter.com/statuses/update.xml" `
                                    "POST" `
                                    "application/x-www-form-urlencoded" `
                                    $tweetstring `
                                    $twitusername `
                                    $twitpassword
        write-debug "Tweeting - Posted status update. Response: $($twitResponseText)"

   }
    
    END {
        #if there was an error, then don't keep the global Twitter
        #credential
        if ($clear) {
            Remove-Variable Twitter_Credential -scope Global
            }
        }
      
} #end Function
 じゃば、使ってみる。
PS 2010/03/28 12:23> . .\fixtwit.ps1
PS 2010/03/28 12:24> "もう昼・・お腹すいた・・" | Out-Twitter
fixtwit.ps1 をドット化して実行。
つぶやきたい言葉をはいて、パイプを通し Out-Twitter を実行。

実行すると資格情報を聞かれるので、
Twitterのアカウントとパスワードを入力する。


入力すると処理が走り、投稿完了。

投稿されていることが確認できた。
URL短縮もされるはずなんだけど、うまく行く時と行かないときがあるような。。
なんでだろう。
↑修正しました。

あくまでツギハギなので本家のスクリプトを見に行ってください。
これをPowerShellのバックグラウンド処理を使えば監視っぽいことはできるかもですね。

2010/03/24

PowerShellの使い方


PowerShellがいくら普及してきた、といってもいきなり
1から10までPowerShellでやるには荷が重いし、
運用管理レベルでは、仰々しく作り込みをするではなく
はじめの内はバッチの中でちょこちょことコマンドレッドを使うというレベルでいいかと思う。
慣れてきたら色々趣向をこらしてやってみるってことで。
(いまだ.NETFrameWork よくわからないし。)

例えば、ここ最近のHotFix適用状況を調べるバッチだとこんな感じで。
 @echo off
:1
echo HotFixチェック
set /p kbmonth=何ヶ月分のFotFixを出力しますか?:

powershell -command "& { Get-HotFix | ? { $_.InstalledOn -ge $(get-date).addmonths(-%kbmonth%) } }"

pause
goto 1
 これをバッチとして用意して実行すれば、
コマンドプロンプトの中でPowerShellを呼び出し、Get-HotFixコマンドレッドを使って
HotFixの適用状況を得ることができます。
HotFixチェック
何ヶ月分のFotFixを出力しますか?:1


Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
BUSO-PC       Update           KB976264      NT AUTHORITY\SYSTEM  2010/03/10...
BUSO-PC       Update           KB980302      NT AUTHORITY\SYSTEM  2010/03/23...



続行するには何かキーを押してください . . .
HotFixチェック
何ヶ月分のFotFixを出力しますか?:2

Source        Description      HotFixID      InstalledBy          InstalledOn
------        -----------      --------      -----------          -----------
BUSO-PC       Security Update  KB971468      NT AUTHORITY\SYSTEM  2010/02/10...
BUSO-PC       Security Update  KB975560      NT AUTHORITY\SYSTEM  2010/02/10...
BUSO-PC       Update           KB976264      NT AUTHORITY\SYSTEM  2010/03/10...
BUSO-PC       Update           KB976662      NT AUTHORITY\SYSTEM  2010/02/24...
BUSO-PC       Update           KB976972      NT AUTHORITY\SYSTEM  2010/01/27...

:(略

まぁはじめはこんな感じで徐々にコマンドレッドを使っていく、という形で。
しかし、この使い方でもPowerShellのリモート機能を組み合わせると結構面白いことができます。
それはまぁ、機会あればまたいずれ。