Powershell 远程管理 (一)

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 //ZB /COPYALL /MIR /R:$retryNum /W:$retrySec}
 }
 
else
 {
 Invoke
-Command -ScriptBlock { robocopy.exe $source $target //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 的实战经验。

posted @ 2010-11-09 13:04  Sai~  阅读(11088)  评论(3编辑  收藏  举报