Powershell 遠端管理 (一)
忙裡偷閒擠出點時間寫寫PS在Windows不錯的管理方式。Powershell 2.0以後可以說是有了質的變化,Modules的加入、ISE、WinRM遠端管理的支援,今天主要講一系列PowerShell在企業級應用的遠端管理,其實也是我這次在部署一個應急方案使用的一些指令碼和方案的集合吧。(我這裡是 域環境,讀者可以自己搭建測試)
首先,我們需要安裝Powershell 2.0和WinRM 2.0 ,這個是作為WindowsUpdate附加補丁得,可以通過可選補丁進行安裝
選中,直接安裝就好了,如果要給所有的伺服器安裝這個補丁,那麼可以考慮用AD環境下的WSUS來安裝這個補丁(關於WSUS的配置我會在以後講述Win2k8 WSUS的文章下詳細說明)。
Powershell好處之一就是文檔很詳細,我們不清楚要多使用Get-Help來查看協助,可以先查閱一些關於遠端相關資料:Get-Help about_remote*,我在使用Powershell 1.0的使用做遠程是相當的痛苦的,每次都要使用WMI的Win32_Process來建立遠程進程,2.0提供了互動Session 以及比較好用的Invoke-Command ,同時對其他的命令提供了-ComputerName的參數,管理起來更加方便。
先說下使用WMI方式做遠程調用吧,首先確認目標機器(需要管理的機器)的遠端管理(Remote Administration)的防火牆是開啟Inbound 允許您的IP傳入的。
開啟Windows進階防火牆 –> 傳入規則(InboundRules) ->遠端管理(Remote Administration)->雙擊開啟對話方塊
選中 Advanced 選擇自己的範圍 我這裡選擇的All,以及在Scope下找到遠程IP地址(Remote IP) 加入 Localsubset 本地子網 然後儲存 啟用規則
這樣一下,我們就允許本地子網對 這台機器的 訪問遠端管理連接埠了(當然你可以根據自己,只給定一個IP訪問目標機器的遠端管理連接埠防火牆)。
如果是域環境,要開啟這個策略,我們可以建立一個GPO,在
編輯GPO對象的策略->電腦配置->管理模版->網路->網路連接->防火牆->域->Windows Firewall:Allow Inbound remote Administration exception的策略,
啟用並且選擇自己需要加入的IP:
然後應用到自己的OU 或者 整個網站(我建議您在部署入域的伺服器先做好各種測試和策略,在入域以後 馬上就會立即生效,那麼也會比較方便,做遠端管理呢。)
先講述三個命令:
Get-WmiObject (1.0+)
Invoke-WmiMethod (2.0)
Invoke-Command (2.0)
大家自行認真查看對應的協助吧,Get-Help Get-WmiObject –Full
WMI調用的話,2.0直接使用Invoke-WmiMethod
比如,我們經常用到的,更新租策略,我記得有一次,我失誤導致大部分機器的3389連接埠全部關閉,遠程連結全部失敗。我更新群組策略,但是沒有GPO生效都要超過90分鐘的,不得已 一些機器的admin$的共用也關閉,不能使用psexec 來遠程調用命令。於是我就用WMI的方式來主動更新群組策略:
代碼function GpupdateForce
{
param
(
[String][parameter(Mandatory=$True)]
[String]$RemoteComputer
)
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "GPUPDATE /FORCE" -EnableAllPrivileges -ComputerName $RemoteComputer
}
這個方法我沒有提供Credential ,就是預設當前登入的域帳號,我們也可以使用
$creq = Get-Credential
然後在Invoke-WmiMethod –Credential $req的方式提供對應的憑據。例如:
代碼function RemoteCall
{
param
(
##調用的命令
[String][parameter(Mandatory=$True)]$Cmd,
##遠端電腦
[String][parameter(Mandatory=$True)]$RemoteComputer
)
$credential = Get-Credential
##可以使用Invoke-Command
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList $Cmd -EnableAllPrivileges -ComputerName $RemoteComputer -Credential $credential
}
如果你的帳號還不是管理員(這裡比較麻煩了,使用WMI的 wmimgmt.msc來添加對應目標機器的許可權,這裡我不提供指令碼了,因為相當的繁瑣,以後有機會和大家說說解決方案吧。二就是dcomcnfg.exe設定您的使用者允許遠程RPC調用的許可權)
WMIMGMT.MSC:
配置WMI命名空間許可權。
DCOMCNFG.EXE:
配置遠程DCOM許可權
當然我們可以直接使用Invoke-Command和互動式Session來簡化WMI的方式,我會在下一篇文章詳細介紹
我就是用這種方式來主動更新的組策略,當時比較著急可能還有更多方案,我在這裡拋磚引玉,畢竟咱不是Pro系統管理員,嘿嘿。
當時的情況。。。當時公司某些情況發生,導致伺服器壓力很大,需要立刻部署20台前端用來負載高負荷的請求,必須安裝IIS,必須同步所有的程式碼,必須迅速建立網站。
首先是代碼同步,其實這種小工具是必須提前做好準備的,比如配置好rsync之類的。因為是突發事件我臨時寫了一個代碼同步的工具,和大家介紹一下強大的robocopy。
代碼同步:
Win2008 是內建這個command 的,如果是2003 需要安裝Resouces Tools 才能使用robocopy
我使用了比較方便的Invoke-Command 。
代碼function CodeSync
{
param([String][parameter(Mandatory=$True)]$source,[String][parameter(Mandatory=$True)]$target,[bool]$mirror = $False,[int]$retryNum = 5,[int]$retrySec = 10)
if($mirror)
{
Invoke-Command -ScriptBlock { robocopy.exe $source $target /E /ZB /COPYALL /MIR /R:$retryNum /W:$retrySec}
}
else
{
Invoke-Command -ScriptBlock { robocopy.exe $source $target /E /ZB /COPYALL /R:$retryNum /W:$retrySec}
}
}
$line = [int]1
Get-Content -Path "E:\Desktop\Target.txt"|%{
$arr = $_.Split(',')
if($arr.Length -ne 3)
{
Write-Host "Line `"$_`" parameter error at line $line`nParameter Format:Source Target Mirror" -ForegroundColor Red
}
else
{
CodeSync $arr[0] $arr[1] ($arr[2] -eq "1")
Write-Host "Task $line Sync Complete!" -ForegroundColor Green
}
$line++
}
Read-Host "Press any key exit..."
這個簡單的指令碼提供了從某個設定檔讀取共用目錄來同步
file://machine1//C$/Test/1,//MACHINE2/c$/Test/2,0
參數1標識Source
參數2標識 Destination
參數3標識 是否完全覆蓋
就這樣,我先把代碼同步到了不同的20個前端。
安裝IIS:
ServerManagerCMD.exe
前面我們提供了RemoteCall的指令碼,聯想到直接使用RemoteCall “ServerManagerCMD.exe –install 角色”,機器名,因此我很順利的安裝了IIS。
部署IIS:
這裡我走了一些彎路,我試圖用 root/WebAdministration 來搞定這一切,但我發現關於IIS WMI的文檔太少了,以至於我基本上沒找到合適的調用方法。後來我嘗試使用了appcmd,也大獲成功了:
思路大致使用RemoteCall 調用 本地的appcmd 來 部署IIS
首先我調用
"C:\Windows\System32\inetsrv\appcmd.exe add site /name:`"test`" /bindings:http://*:80 /physicalpath:`"C:\test\ `""
添加了網站 test,而且綁定了 所有IP地址的80連接埠,路徑是:C:\test\
注意:在Powershell中的字串出現了雙引號,要使用 “`”(1左邊的鍵)來轉義。
然後
"C:\Windows\System32\inetsrv\appcmd.exe start site `"f-sq`""
我開啟了網站,預設是關閉的。
"C:\Windows\System32\inetsrv\appcmd.exe delete site `"Default Web Site`""
我刪除了所有機器的預設網站
"C:\Windows\System32\inetsrv\appcmd.exe set config /section:httplogging /dontlog:True"
並且禁用了 本地的IIS 日誌
"C:\Windows\System32\inetsrv\appcmd.exe add apppool /name:`"test`" /queueLength:50000 /processModel.userName:`"test\test`" /processModel.password:`"%^&*(234`" /processModel.loadUserProfile:`"True`" /processModel.maxProcesses:5
/failure.loadBalancerCapabilities:`"TcpLevel`" /failure.rapidFailProtectionMaxCrashes:50
/processModel.identityType:`"SpecificUser`""
建立了新的應用程式集區 制定了背景工作執行緒,隊列長度,自訂網域帳號等。
"C:\Windows\System32\inetsrv\appcmd.exe set site /site.name:`"f-sq`" /applicationDefaults.applicationPool:`"test`""
最後將網站綁定到test 應用程式集區
•整個過程只話了一個多小時,試想如果以後再來100台前端機器,那麼可能只要1分鐘時間就能搞定這個任務了。所以說積累也很重要!
本文已實際的經曆描述,希望能協助到大家,在一篇文章中我會說到PSSession 的實戰經驗。