翻譯|使用教程|編輯:莫成敏|2019-10-30 14:08:30.150|閱讀 201 次
概述:本文演示了如何使用XML argfiles將參數傳遞給SQL Compare,從而消除了每個目標數據庫所需的許多修改數據庫模式比較和部署過程所涉及的繁瑣腳本教程的后半部分內容——使用XML argfile執行SQL Compare CLI、動態生成argfile、密碼存儲問題。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
SQL Compare是一款比較和同步SQL Server數據庫結構的工具。現有超過150,000的數據庫管理員、開發人員和測試人員在使用它。當測試本地數據庫,暫存或激活遠程服務器的數據庫時,SQL Compare將分配數據庫的過程自動化。
本文演示了如何使用XML argfiles將參數傳遞給SQL Compare,從而消除了每個目標數據庫所需的許多修改數據庫模式比較和部署過程所涉及的繁瑣腳本。本文是后半部分內容,介紹了使用XML argfile執行SQL Compare CLI、動態生成argfile、密碼存儲問題。
使用XML argfile執行SQL Compare CLI
以下1-liner將在ArgFile目錄中執行所有XML argfile:
<# now we can execute sql Compare CLI with all the argfiles #> Get-ChildItem -Path "${env:temp}" -Filter '*.xml'| foreach{SQLCompare "/Argfile:$($_.fullname)"}
動態生成argfile
如果您沒有任何argfiles怎么辦?我們可以即時生成它們!一旦存在argfile,您就可以在每次要重新執行它時使用上面的一行程序。
這是我們的第一個簡單版本,可即時生成用于為每個提供的數據庫制作快照的argfile。盡管它很好,但是如果您使用的是SQL Server身份驗證而不是Windows身份驗證,則存在未加密的密碼問題,如果您使用的是Linux或MacOS,則可能會出現這種情況。
<# We just have a list of servers, databases and (in this case userids and passwords) #> @( @{ 'Database' = 'Sigrid'; 'Server' = 'MyOtherServer'; 'userid' = 'MyUsername'; 'password' = 'MyP@55w0rd' }, @{ 'Database' = 'Abnego'; 'Server' = 'MyOtherServer'; 'userid' = 'MyUsername'; 'password' = 'MyP@55w0rd' }, @{ 'Database' = 'Antipas'; 'Server' = 'MyOtherServer'; 'userid' = 'MyUsername'; 'password' = 'MyP@55w0rd' }, @{ 'Database' = 'Archaelus'; 'Server' = 'MyOtherServer'; 'userid' = 'MyUsername'; 'password' = 'MyP@55w0rd' }, @{ 'Database' = 'Adeliza'; 'Server' = 'MyFirstServer' }, @{ 'Database' = 'Sigrid'; 'Server' = 'MyFirstServer' } ) | foreach{ "<?xml version=""1.0""?> <!-- make a snapshot of a database $($_.Database) on $($_.Server) --> <commandline> <Server1>$($_.Server)</Server1> <database1>$($_.Database)</database1> $(if ($_userid -ne $null) { "<userName1>$($_.userid)</userName1> <password1>$($_.password)</password1>" }) <loglevel>Warning</loglevel> <force /> <makesnapshot>${env:temp}\$($_.Database)-$($_.Server).snp</makesnapshot> <options>default</options> </commandline> ">"${env:temp}\Snap-$($_.Database)-$($_.Server).xml" } <# now we can execute sql Compare CLI with all the argfiles #> Get-ChildItem -Path "${env:temp}" -Filter 'Snap*.xml' | foreach{ SQLCompare "/Argfile:$($_.fullname)" }
突然,我們現在有了很多快照,以及一種將實時數據庫與快照進行比較的方法,以使我們能夠確定更改內容,然后允許使用這些更改來保存這些更改。
密碼存儲問題
如前所述,許多讀者會為在文件中放置未加密的密碼而大驚小怪。這總是一個壞主意。好的,將它們保存在您的用戶區域中,以便獲得NTFS訪問控制所提供的保護措施。但是,密碼也必須加密。
實際上,如果您完全使用SQL Server身份驗證,那么您的SQL Compare項目文件也應存儲在您的用戶區域中(在PowerShell中,“${env:temp}”是指您用戶區域內的臨時目錄)。這是因為,盡管密碼是在項目文件中加密的,但這樣做的方式是,無論Windows / Linux身份如何,任何人都可以使用加密的密碼,并且他們可以粘貼到其項目文件中以使用SQL Compare訪問數據庫。
要存儲憑據,Microsoft建議在PowerShell中使用Import-CliXml和Export-CliXml。Export-Clixmlcmdlet使用Windows數據保護API加密憑據對象。加密可確保只能通過您的用戶帳戶以及僅在該計算機上解密憑據對象的內容。導出的CLIXML argfile不能在其他計算機上或該計算機上的其他用戶使用。
這是如何在磁盤上存儲密碼的示例。我只想列出有關服務器上數據庫的所有詳細信息,并且我希望有一個例程可以安全地執行此操作,而不管我使用的是Windows身份驗證還是SQL Server身份驗證:
import-Module sqlserver #import all the libraries for SMO $SQLserver = 'MyFirstServer' $SqlUserName = 'MyUsername' if ($SqlUserName -ne $null) { $SqlEncryptedPasswordFile = ` "$env:USERPROFILE\$($SqlUserName)-$($SQLserver).xml" # test to see if we know about the password in a secure string stored in the user area if (Test-Path -path $SqlEncryptedPasswordFile -PathType leaf) { #has already got this set for this login so fetch it $SqlCredentials = Import-CliXml $SqlEncryptedPasswordFile } else #then we have to ask the user for it (once only) { #hasn't got this set for this login $SqlCredentials = get-credential -Credential $SqlUserName $SqlCredentials | Export-CliXml -Path $SqlEncryptedPasswordFile } $ServerConnection = new-object ` "Microsoft.SqlServer.Management.Common.ServerConnection" ` ('MyFirstServer', $SqlCredentials.UserName, $SqlCredentials.Password) } else { $ServerConnection = new-object "Microsoft.SqlServer.Management.Common.ServerConnection" ` ($csb.server) } $s = new-object ("Microsoft.SqlServer.Management.Smo.Server") $ServerConnection $s.Databases
SQL Compare argfiles的問題在于命令行界面通過CLI直接從磁盤讀取它們,并且我們不允許將敏感信息(例如密碼)作為參數單獨傳遞。這意味著在產品中必須解決在argfile中以純文本格式存儲密碼的問題。
在Argfiles中存儲密碼的解決方案
為了快速解決此問題,并為現有的SQL Compare用戶提供解決方案,我們需要“動態”添加密碼。
讓我們從這些argfiles重新開始。現在,我們不會在其中輸入密碼。如果他們有用戶名,那么我們需要即時添加一個適當的密碼,以創建XML argfile的臨時版本,然后將其傳遞給SQL Compare。它可以是username1或 username2,也可以是password1或 password2。
<# We just have a list of servers, databases and (in this case Userids and logins) #> @( @{ 'Database' = 'Sigrid'; 'Server' = 'MyOtherServer' }, @{ 'Database' = 'Abednego'; 'Server' = 'MyOtherServer' }, @{ 'Database' = 'Antipas'; 'Server' = 'MyOtherServer' }, @{ 'Database' = 'Archaelus'; 'Server' = 'MyOtherServer'; 'userid' = 'MyUsername' }, @{ 'Database' = 'Adeliza'; 'Server' = 'MyFirstServer'; 'userid' = 'MyUsername' }, @{ 'Database' = 'Sigrid'; 'Server' = 'MyFirstServer'; 'userid' = 'MyUsername' } ) | foreach{ "<?xml version=""1.0""?> <!-- make a snapshot of a database $($_.Database) on $($_.Server) --> <commandline> <Server1>$($_.Server)</Server1> <database1>$($_.Database)</database1> $(if ($_.userid -ne $null) { "<userName1>$($_.userid)</userName1> <password1>$($_.password)</password1>" }) <loglevel>Warning</loglevel> <force /> <makesnapshot>${env:temp}\$($_.Database)-$($_.Server).snp</makesnapshot> <options>default</options> </commandline> ">"${env:temp}\Snap-$($_.Database)-$($_.Server).xml" }
現在,我們必須創建一個幫助函數來獲取密碼。當您第一次對任何用戶和服務器運行此功能時,都會從您那里獲取密碼,并且必須輸入該密碼。此后,它將從安全存儲中獲取該密碼。
function SavedPassword ($SqlUserName, $server) { $SqlEncryptedPasswordFile = ` "$env:USERPROFILE\$($SqlUserName)-$($server).xml" # test to see if we know about the password in a secure string stored in the user area if (Test-Path -path $SqlEncryptedPasswordFile -PathType leaf) { #has already got this set for this login so fetch it $SqlCredentials = Import-CliXml $SqlEncryptedPasswordFile } else #then we have to ask the user for it (once only) { #hasn't got this set for this login $SqlCredentials = get-credential -Credential $SqlUserName $SqlCredentials | Export-CliXml -Path $SqlEncryptedPasswordFile } $SqlCredentials.GetNetworkCredential().password }
現在,我們重新開始。遺憾的是,它在代碼中有點復雜,但這絲毫不會減慢速度。我們依次提取每個argfile,查看它是否需要密碼,如果需要,請插入密碼。我們將每個副本復制到一個新的臨時文件,并將其傳遞給SQL Compare。使用它后,我們會立即將其刪除!
Get-ChildItem -Path "${env:temp}" -Filter 'Snap-*.xml' | foreach{ $content = [System.IO.File]::ReadAllText($_.fullname); $xmlContent = [xml]$content write-output "$($xmlContent.'#comment')" $server1 = $xmlContent.commandline.server1 $server2 = $xmlContent.commandline.server2 $username1 = $xmlContent.commandline.username1 $username2 = $xmlContent.commandline.username2 if ($username1 -ne $null) { $xmlContent.commandline.password1 = (SavedPassword $username1 $server1) } if ($username2 -ne $null) { $xmlContent.commandline.password2 = (SavedPassword $username2 $server2) } $Tempfile="${env:temp}\Temp_$($_.basename).xml" $xmlContent.Save($Tempfile) SQLCompare "/Argfile:$Tempfile" Remove-Item -Path "$Tempfile" }
結論
我最喜歡使用argfiles將參數傳遞給SQL Compare的地方是,您可以通過將特定任務所需的所有argfile收集到目錄中,然后依次將每個argfile傳遞給SQL Compare來完成很多工作。它削減了很多腳本,意味著您可以通過添加、修改或刪除argfile來修改整體任務。與項目文件不同,這些XML argfile可以通過腳本或在文本編輯器中輕松修改。
如前所述,如果您選擇使用argfiles并使用PowerShell,則需要解決未加密密碼的問題。
本教程內容到這里就結束了,喜歡的朋友可以繼續關注我們,了解更多金喜正規買球相關的文章資訊!您也可以點擊下載SQL Compare試用版體驗一下~
相關內容推薦:
SQL Compare教程:在Argfiles中使用SQL Compare命令行(上)
想要購買SQL Compare正版授權,或了解更多產品信息請點擊
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn