翻譯|使用教程|編輯:莫成敏|2019-10-30 14:08:30.150|閱讀 201 次
概述:本文演示了如何使用XML argfiles將參數(shù)傳遞給SQL Compare,從而消除了每個(gè)目標(biāo)數(shù)據(jù)庫所需的許多修改數(shù)據(jù)庫模式比較和部署過程所涉及的繁瑣腳本教程的后半部分內(nèi)容——使用XML argfile執(zhí)行SQL Compare CLI、動態(tài)生成argfile、密碼存儲問題。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
SQL Compare是一款比較和同步SQL Server數(shù)據(jù)庫結(jié)構(gòu)的工具。現(xiàn)有超過150,000的數(shù)據(jù)庫管理員、開發(fā)人員和測試人員在使用它。當(dāng)測試本地?cái)?shù)據(jù)庫,暫存或激活遠(yuǎn)程服務(wù)器的數(shù)據(jù)庫時(shí),SQL Compare將分配數(shù)據(jù)庫的過程自動化。
本文演示了如何使用XML argfiles將參數(shù)傳遞給SQL Compare,從而消除了每個(gè)目標(biāo)數(shù)據(jù)庫所需的許多修改數(shù)據(jù)庫模式比較和部署過程所涉及的繁瑣腳本。本文是后半部分內(nèi)容,介紹了使用XML argfile執(zhí)行SQL Compare CLI、動態(tài)生成argfile、密碼存儲問題。
使用XML argfile執(zhí)行SQL Compare CLI
以下1-liner將在ArgFile目錄中執(zhí)行所有XML argfile:
<# now we can execute sql Compare CLI with all the argfiles #> Get-ChildItem -Path "${env:temp}" -Filter '*.xml'| foreach{SQLCompare "/Argfile:$($_.fullname)"}
動態(tài)生成argfile
如果您沒有任何argfiles怎么辦?我們可以即時(shí)生成它們!一旦存在argfile,您就可以在每次要重新執(zhí)行它時(shí)使用上面的一行程序。
這是我們的第一個(gè)簡單版本,可即時(shí)生成用于為每個(gè)提供的數(shù)據(jù)庫制作快照的argfile。盡管它很好,但是如果您使用的是SQL Server身份驗(yàn)證而不是Windows身份驗(yàn)證,則存在未加密的密碼問題,如果您使用的是Linux或MacOS,則可能會出現(xiàn)這種情況。
<# 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)" }
突然,我們現(xiàn)在有了很多快照,以及一種將實(shí)時(shí)數(shù)據(jù)庫與快照進(jìn)行比較的方法,以使我們能夠確定更改內(nèi)容,然后允許使用這些更改來保存這些更改。
密碼存儲問題
如前所述,許多讀者會為在文件中放置未加密的密碼而大驚小怪。這總是一個(gè)壞主意。好的,將它們保存在您的用戶區(qū)域中,以便獲得NTFS訪問控制所提供的保護(hù)措施。但是,密碼也必須加密。
實(shí)際上,如果您完全使用SQL Server身份驗(yàn)證,那么您的SQL Compare項(xiàng)目文件也應(yīng)存儲在您的用戶區(qū)域中(在PowerShell中,“${env:temp}”是指您用戶區(qū)域內(nèi)的臨時(shí)目錄)。這是因?yàn)?,盡管密碼是在項(xiàng)目文件中加密的,但這樣做的方式是,無論Windows / Linux身份如何,任何人都可以使用加密的密碼,并且他們可以粘貼到其項(xiàng)目文件中以使用SQL Compare訪問數(shù)據(jù)庫。
要存儲憑據(jù),Microsoft建議在PowerShell中使用Import-CliXml和Export-CliXml。Export-Clixmlcmdlet使用Windows數(shù)據(jù)保護(hù)API加密憑據(jù)對象。加密可確保只能通過您的用戶帳戶以及僅在該計(jì)算機(jī)上解密憑據(jù)對象的內(nèi)容。導(dǎo)出的CLIXML argfile不能在其他計(jì)算機(jī)上或該計(jì)算機(jī)上的其他用戶使用。
這是如何在磁盤上存儲密碼的示例。我只想列出有關(guān)服務(wù)器上數(shù)據(jù)庫的所有詳細(xì)信息,并且我希望有一個(gè)例程可以安全地執(zhí)行此操作,而不管我使用的是Windows身份驗(yàn)證還是SQL Server身份驗(yàn)證:
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直接從磁盤讀取它們,并且我們不允許將敏感信息(例如密碼)作為參數(shù)單獨(dú)傳遞。這意味著在產(chǎn)品中必須解決在argfile中以純文本格式存儲密碼的問題。
在Argfiles中存儲密碼的解決方案
為了快速解決此問題,并為現(xiàn)有的SQL Compare用戶提供解決方案,我們需要“動態(tài)”添加密碼。
讓我們從這些argfiles重新開始。現(xiàn)在,我們不會在其中輸入密碼。如果他們有用戶名,那么我們需要即時(shí)添加一個(gè)適當(dāng)?shù)拿艽a,以創(chuàng)建XML argfile的臨時(shí)版本,然后將其傳遞給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" }
現(xiàn)在,我們必須創(chuàng)建一個(gè)幫助函數(shù)來獲取密碼。當(dāng)您第一次對任何用戶和服務(wù)器運(yùn)行此功能時(shí),都會從您那里獲取密碼,并且必須輸入該密碼。此后,它將從安全存儲中獲取該密碼。
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 }
現(xiàn)在,我們重新開始。遺憾的是,它在代碼中有點(diǎn)復(fù)雜,但這絲毫不會減慢速度。我們依次提取每個(gè)argfile,查看它是否需要密碼,如果需要,請插入密碼。我們將每個(gè)副本復(fù)制到一個(gè)新的臨時(shí)文件,并將其傳遞給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" }
結(jié)論
我最喜歡使用argfiles將參數(shù)傳遞給SQL Compare的地方是,您可以通過將特定任務(wù)所需的所有argfile收集到目錄中,然后依次將每個(gè)argfile傳遞給SQL Compare來完成很多工作。它削減了很多腳本,意味著您可以通過添加、修改或刪除argfile來修改整體任務(wù)。與項(xiàng)目文件不同,這些XML argfile可以通過腳本或在文本編輯器中輕松修改。
如前所述,如果您選擇使用argfiles并使用PowerShell,則需要解決未加密密碼的問題。
本教程內(nèi)容到這里就結(jié)束了,喜歡的朋友可以繼續(xù)關(guān)注我們,了解更多金喜正規(guī)買球相關(guān)的文章資訊!您也可以點(diǎn)擊下載SQL Compare試用版體驗(yàn)一下~
相關(guān)內(nèi)容推薦:
SQL Compare教程:在Argfiles中使用SQL Compare命令行(上)
想要購買SQL Compare正版授權(quán),或了解更多產(chǎn)品信息請點(diǎn)擊
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn