Synchronize 兩台 IIS7

使用了兩種不同的方法去 synchronize 兩台 IIS7,記錄下來供日後參考。

  1. 用 WebDeploy + Robocopy
  2. 用 Appcmd + Robocopy (這個辦法比較好)

WebDeploy + Robocopy

首先在 source 啟動 WebDepSv:


net start webdepsv

然後在 destination 使用以下的 command 續一把 website 從 source sync 至 destination:
Continue reading “Synchronize 兩台 IIS7”

利用 PowerShell 自動 Restore 數據庫

也是三部曲,首先是準備 PowerShell 的 restore script,接著是利用一個 batch file (.BAT) 啟動這個 script 檔案,最後就是在 Task Scheduler 創建一個 task 按時執行這個 batch file 就完成了。
PowerShell script file 稱為 SqlRestore.ps1,內容如下:

#============================================================
# Restore a Database using PowerShell and SQL Server SMO
# Restore to the same database, overwrite existing db
# Donabel Santos
# 2010.10.16 paulus: modified
#============================================================

#clear screen
cls

#load assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

#get backup file
#you can also use PowerShell to query the last backup file based on the timestamp
#I'll save that enhancement for later
$backupFile = "C:MSSQLBackup" + $args[0] + ".bak"

#we will query the db name from the backup file later

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File")
$smoRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")

#settings for restore
$smoRestore.NoRecovery = $false;
$smoRestore.Partial = $false
$smoRestore.ReplaceDatabase = $true;
$smoRestore.Action = "Database"

#show every 10% progress
$smoRestore.PercentCompleteNotification = 10;

$smoRestore.Devices.Add($backupDevice)

#read db name from the backup file's backup header
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server)

#display database name
"Database Name from Backup Header : " + $smoRestoreDetails.Rows[0]["DatabaseName"]

$smoRestore.Database = $smoRestoreDetails.Rows[0]["DatabaseName"]

#restore
$smoRestore.SqlRestore($server)

#2010.10.16 paulus: set owner to sa
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $server.Databases.Item($smoRestoreDetails.Rows[0]["DatabaseName"])
$db.SetOwner("sa", $TRUE)

"Done"

 

batch file 稱為 RestoreDb.bat,內容如下:

powershell -command "& {C:MSSQLSqlRestore.ps1 Club.Secretary}"

powershell -command "& {C:MSSQLSqlRestore.ps1 Club.Secretary.RTIA}"

batch file 比較簡單,再來就是設立 Task Scheduler。如果 Task Scheduler 啟動的時間比 Backup 的時間早,就可以做成有兩天的備份了。

配合之前講的 Backup script 便建立了一個 SQL Server 的 mirrror server, 用作 disaster backup, 雖然不是 synchronized,難得是免費的,效果也算不壞吧?

利用 PowerShell 做 SQL 數據庫備份

分成三個部份,首先是準備 PowerShell 的 backup script,接著是利用一個 batch file (.BAT) 啟動這個 script 檔案,最後就是在 Task Scheduler 創建一個 task 按時執行這個 batch file 就完成了。

PowerShell script file 稱為 SqlBackup.ps1,內容如下:

#============================================================
# Backup a Database using PowerShell and SQL Server SMO
# Script below creates a full backup
# Donabel Santos
# 2010.10.16 paulus:modified
#============================================================

#specify database to backup
#ideally this will be an argument you pass in when you run
#this script, but let's simplify for now
$dbToBackup = $args[0]

#clear screen
cls

#load assemblies
#note need to load SqlServer.SmoExtended to use SMO backup in SQL Server 2008
#otherwise may get this error
#Cannot find type [Microsoft.SqlServer.Management.Smo.Backup]: make sure
#the assembly containing this type is loaded.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
#Need SmoExtended for smo.backup
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

#create a new server object
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"
$backupDirectory = $server.Settings.BackupDirectory

#2010.10.16 paulus: display default backup directory
"Default Backup Directory: " + $backupDirectory

#display current backup database
"Current database: " + $dbToBackup

$db = $server.Databases[$dbToBackup]
$dbName = $db.Name

$timestamp = Get-Date -format yyyyMMddHHmmss
$smoBackup = New-Object ("Microsoft.SqlServer.Management.Smo.Backup")

#BackupActionType specifies the type of backup.
#Options are Database, Files, Log
#This belongs in Microsoft.SqlServer.SmoExtended assembly

$smoBackup.Action = "Database"
$smoBackup.BackupSetDescription = "Full Backup of " + $dbName
$smoBackup.BackupSetName = $dbName + " Backup"
$smoBackup.Database = $dbName
$smoBackup.MediaDescription = "Disk"
#2010.10.16 paulus: overwrite
$smoBackup.Initialize = $TRUE
#2010.10.16 paulus: no need for timestamp
#$smoBackup.Devices.AddDevice($backupDirectory + "" + $dbName + "_" + $timestamp + ".bak", "File")
$smoBackup.Devices.AddDevice($backupDirectory + "" + $dbName + ".bak", "File")
$smoBackup.SqlBackup($server)

#let's confirm, let's list list all backup files
$directory = Get-ChildItem $backupDirectory

#list only files that end in .bak, assuming this is your convention for all backup files
$backupFilesList = $directory | where {$_.extension -eq ".bak"}
$backupFilesList | Format-Table Name, LastWriteTime

batch file 稱為 BackupDb.bat,內容如下:

del C:MSSQLBackup*.* /F /Q
powershell -command "& {C:MSSQLSqlBackup.ps1 Club.Secretary}"
powershell -command "& {C:MSSQLSqlBackup.ps1 Club.Secretary.RTIA}"
robocopy C:MSSQLBackup \151-SQL2K8C$MSSQLBackup /Z /W:5 /MIR

第一行,把檔案夾內的舊 backup files 刪除。
第二行,啟動 Powershell script 備份數據庫 Club.Secretary。
第三行,再用 PowerShell script 備份數據庫 Club.Secretary.RTIA。
如此安排是容許選擇性地 backup SQL Server 內的 databases.
第四行,用 RoboCopy 把剛才備份的檔案抄至指定的 computer 151-SQL2K8 去,RoboCopy 用了一個 /MIR 意思是 Mirror, 確保 151-SQL2K8 收到的檔案跟本機完全相同,不多也不少。

最後的設定 Task Scheduler 就不用講了吧?

PowerShell 的 Set-ExecutionPolicy

最初的原意是利用 PowerShell 做一個 SQL 數據庫備份,然後利用 Task Scheduler 變成按時每天自動 backup 數據庫 一次。一開始就碰上了這個 Set-ExecutionPolicy 的麻煩,找到解決辦法後順便把它記錄下來。

PowerShell 的 SecurityPolicy default 是 Restricted,Restricted 是最嚴格的,不過就會影響到一些指令會由於 Security Level 不足而執行不了,例如我今次要做的 SQL backup 有需要用到一些 SMO (SQL Server Management Objects),這樣 Restricted 就行不通了。

如果在 PowerShell 的 console 中可以執行 Set-ExecutionPolicy 去改變目前的 Security Level,例如:

PS> Set-SecutrityPolicy RemoteSigned

不過在 Task Scheduler 就不可以這樣,唯一可行的方法是把本機的 policy 更改。
Continue reading “PowerShell 的 Set-ExecutionPolicy”