Powershellでタスクスケジューラのタスクをまとめてエクスポートするスクリプト
サーバーに多数タスクが登録されているのですが、 何かあった時のためにタスクをエクスポートし、バックアップしようと思い作成。
前提
以下の環境を前提とします。
- Scheduled Tasks Cmdletsが使える
ソースコード
$taskBasePath = "\MyTask\*" $taskSaveDir = "C:\MyTaskBackup" Get-ScheduledTask -TaskPath $taskBasePath | foreach { $taskDir = Join-Path $taskSaveDir $_.TaskPath if( -not (Test-Path -Path $taskDir)) { mkdir -Path $taskDir } $path = (Join-Path $taskDir "$($_.TaskName).xml") Export-ScheduledTask -TaskName $_.TaskName -TaskPath $_.TaskPath | Out-File $path # -WhatIf }
解説
使う時書き換える変数については以下表を参照。
変数 | 用途 | 備考 |
---|---|---|
taskBasePath | タスクスケジューラの特定のパス。 | このフォルダにまとめて定義しておけばよいという運用をしてます。 |
taskSaveDir | 保存先のパス。 | ここをSVNやGITのリポジトリに指定して定期的に自動コミット/プッシュしたりしたい。 |
動作としては 指定のパスのタスクを、格納しているフォルダの中に、そのタスク名で保存する という感じです。
無いフォルダは勝手に作ります。
既存のタスクを削除したりはしないので何度でも実行可能。
参考
Scheduled Tasks Cmdlets in Windows PowerShell
以上!
チートシート的メモ
概要
1,2行のちょっとしたコードをまとめる。
ちょいちょい更新していく。
PowerShell
現在のスクリプトのディレクトリを取得する。
Split-Path $MyInvocation.MyCommand.Path # pushd %~dp0と同じ処理 Push-Location -Path (Split-Path $MyInvocation.MyCommand.Path)
バッチ(コマンドプロンプト)
BCPで[-w]オプションつけて出力するとforで読めない
単純な文字列型[-c]にしよう。
javascript
getElementsByTagNameの結果をforEachする
Array.prototype.slice.callを使って配列に変換する必要がある。
Array.prototype.slice.call(document.getElementsByTagName("table")).forEach...
BCPコマンドで同一構造のサーバーのテーブルを比較する。
作ったのでメモ。
経緯
DBサーバーを入れ替える時、全データが入替えられているか確認する作業があったのですが、
「SSMSでSelectして目視比較して・・・」みたいな話が持ち上がり初めていたので必死で書きました。
どう考えても目視はやばい。
構造
以下の2ファイルを同一ディレクトリに用意して使います。
- このバッチ
- DB名とテーブル名を持つCSV
以下のように処理してDBのデータを比較します。
- 新旧サーバーの対象のテーブルに対してBCPでエクスポート
- エクスポートの結果をfcコマンドで比較。fcのログを出す。
- 同一なら先頭にok
- 相違なら先頭にngがつく
バッチのソース
@echo off setlocal pushd %~dp0 rem DBとテーブルのリストファイル名 set targetList= rem ユーザーのアカウント set OldSvrUser= set NewSvrUser= set OldSvrPass= set NewSvrPass= rem 比較サーバーインスタンス set OldServer= set NewServer= rem 出力先フォルダ powershell -Command "$(Get-Date).ToString('yyyyMMdd_HHmmss')" > %temp%\ret set /p ymd=< %temp%\ret set BaseFolder=%UserProfile%\Desktop\SvrDataComp\%ymd%\ set OldFolder=%BaseFolder%Old\ set NewFolder=%BaseFolder%New\ mkdir %BaseFolder% mkdir %OldFolder% mkdir %NewFolder% rem 指定のリストからループして出力 for /f "tokens=1,2* delims=," %%i in (%targetList%) do ( call :CompareOldNewServer %%i %%j ) popd endlocal exit rem -------------------------------------------------------------------------------------- rem エクスポート処理 rem -------------------------------------------------------------------------------------- :ExportTable rem 引数 set instance=%1 set db=%2 set table=%3 set exportPath=%4 set usr=%5 set pass=%6 TITLE Exporting [Server:%instance% DB:%db% Table:%table%] bcp "SELECT * FROM %db%.dbo.%table%" queryout %exportPath% -S %instance% -U%usr% -P%pass% -w -k -o %exportPath%.log exit /b rem -------------------------------------------------------------------------------------- rem 新旧サーバーのテーブルのエクスポートと比較 rem -------------------------------------------------------------------------------------- :CompareOldNewServer rem 引数 set db=%1 set table=%2 set fileName=%db%_%table%.txt set oldExport=%OldFolder%%fileName% set newExport=%NewFolder%%fileName% call :ExportTable %OldServer% %db% %table% %oldExport% %OldSvrUser% %OldSvrPass% call :ExportTable %NewServer% %db% %table% %newExport% %NewSvrUser% %NewSvrPass% set compFile=%BaseFolder%ng_%db%_%table%.txt fc /a /c /n /u %oldExport% %newExport% > %compFile% if "%errorlevel%"=="0" move %compFile% %BaseFolder%ok_%db%_%table%.txt exit /b
Powershellでバッチ処理の時に日時をらくに取得する。
powershell -Command "$(Get-Date).ToString('yyyyMMdd_HHmmss')" > %temp%\ret set /p ymd=< %temp%\ret
.Netに慣れているため、このスタイルで日付にできると楽でいいですね。
あと最近TEMPフォルダに結果をリダイレクトして変数に戻してくる方法が楽で使ってます。
直接代入できればいいのになぁ。
PowerShellで現在参加しているドメインの各メンバーのパスワード期限を取得する。
下記記事で環境構築しておきながら全部どっとねっとで済ましてしまった。
SamAccountNameと残り日数CSV出力にしてなんやかんやする予定。
ソースコード
Add-Type -AssemblyName System.DirectoryServices Add-Type -AssemblyName System.DirectoryServices.AccountManagement $context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext( [System.DirectoryServices.AccountManagement.ContextType]::Domain, [System.Environment]::UserDomainName) $up = New-Object System.DirectoryServices.AccountManagement.UserPrincipal($context) $searcher = New-Object System.DirectoryServices.AccountManagement.PrincipalSearcher($up) $allUsers = $searcher.FindAll() foreach($user in $allUsers){ # 有効なアカウントのみ if($user.Enabled) { $deUser = [System.DirectoryServices.DirectoryEntry]$user.GetUnderlyingObject() $expDate = ([System.DateTime]$deUser.PasswordExpirationDate) # 今から期限までの期間を取得 $ts = New-TimeSpan (Get-Date) $expDate # とりあえず前後10日の期間で計算する。 if ( $ts.Days -lt 10 -and $ts.Days -igt -10 ){ Write-Output ([string]::Join(",", @( $user.SamAccountName, $ts.Days))) } } }
Windows7にPowerShell用のActiveDirectoryモジュールをインストールする。
ADサーバーにデフォルトでインストールされているPowershellのADモジュールをWindows7でも使いたい。
手順
手順については以下のURLを参照した。というかそのままです。
How to add Active Directory module in PowerShell in Windows 7 – SharePoint and Others
1. インストール
- Download Windows 7 Service Pack 1 (SP1) 用のリモート サーバー管理ツール from Official Microsoft Download Center ** Windows6.1-KB958830-x86-RefreshPkg.msu
2. 機能の有効化
Windowsの機能の有効化または無効化 ココ!
確認
Windows Powershell ISEのコマンドエクスプローラ?にてモジュールにActiveDirectoryがあればOK
PowerShellで実行中のPCのActive Directoryのパスワード期限を取得する。
ADのモジュールはADサーバーしかインポートできないみたいですね。
ということで.Netを利用して作りました。
Add-Type -AssemblyName System.DirectoryServices $adPath = [string]::Format("WinNT://{0}/{1}", [System.Environment]::UserDomainName, [System.Environment]::UserName) $de = New-Object System.DirectoryServices.DirectoryEntry $adPath # パスワード期限の取得 $expDt = [System.DateTime]$de.PasswordExpirationDate echo $expDt # 差分を取得 $ts = New-TimeSpan (Get-Date) $expDt echo $ts