今天早上接了个邮件,需要在所有的windows 2008R2的服务器上都安装 .net 4.5和 WMF4( PowerShell 4.0)。
豆子做了些研究,觉得需要做到以下几点
扫描所有的windows 2008 R2服务器,能够查看4.5和Powershell的当前版本是什么;
如果需要安装,必须以先安装.net 4.5, 然后安装WMF4的顺序进行,不然会出现安装显示正常,但是WMF4并未完全安装的问题。
安装的方式,可以采用MSI+MST的自定义安装,或者使用开机/关机的脚本执行,或者通过powrshell或者psexec 的远程命令直接安装
第一点我可以通过Powershell脚本实现,通过get-adcomputer获取对应的服务器对象,然后对每一个对象进行invoke-command的远程操作,查看注册表和powershell版本即可。
查看.net 的版本和ps的版本
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -name Version -EA 0 | Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} | Sort-Object version -Descending | Select-Object -ExpandProperty Version -First 1
$PSVersionTable.PSVersion.Major
需要注意的一点是,在所有的远程服务器上面,必须启动了winrm的服务,并打开了对应的防火墙接口才能执行invoke-command命令。一个简单的命令是winrm quickconfig 可以自动启动并配置防火墙。考虑到机器比较多,豆子使用的是组策略来统一更改。
具体的配置可以参考
http://blog.powershell.no/2010/03/04/enable-and-configure-windows-powershell-remoting-using-group-policy/
第二点,必须注意的是windows 2008 R2对应的WMF4其实是一个升级补丁,可以通过下面命令查看一下是否真正安装了,否则如果安装顺序不对,这个补丁不会安装的。
$status=get-hotfix| Where-Object {$_.hotfixid -eq "KB2819745"} if ($status) { Write-host " WMF4 is Installed " } else { Write-host "WMF4 is Not Installed" }
第三点,具体的安装方式,最开始我打算直接用powershell远程session直接从共享网络上安装就行了,后来发现微软默认的安全机制会禁止这种连续跳转的权限。比如我从机器A上远程控制机器B,然后从机器C的共享里面安装程序是被严厉禁止的,这是为了避免中间人攻击。
可以通过激活credssp的方式执行,参考如下,但是为了避免安全隐患,豆子还是决定放弃
http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/14/enable-powershell-quot-second-hop-quot-functionality-with-credssp.aspx
MST+MSI的安装方式比较麻烦,需要用orca修改对应的属性,这里豆子也放弃了,感兴趣的可以参考这个博客
http://www.itninja.com/blog/view/deploy-net-dot-net-4-5-1-via-gpo
最后的选择则是关机脚本
两个脚本
安装.net 4.5
rem script to install .net 4.5 @echo off reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SKUs\.NETFramework,version=v4.5" if %errorlevel%==1 goto installnet if %errorlevel%==0 goto exit :installnet start /wait "\\syd02\Syd_Transfer\yli\dotnetfx45_full_setup.exe /ceipconsent /norestart /q" :exit exit
安装 WMF4
@echo off pushd %~dp0 echo %CD% reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\powerShellEngine" /f 4.0 if %errorlevel%==1 goto installwmf if %errorlevel%==0 goto exit :installwmf expand -f:* \\syd02\syd_transfer\yli\Windows6.1-KB2819745-x64-MultiPkg.msu %temp% pkgmgr.exe /n:%temp%\Windows6.1-2819745-x64.xml /norestart /quiet :exit
把上面的脚本配置成关机脚本,注意安装顺序,重启服务器就会自动安装。
最后给个比较完整的脚本
$a=Get-ADComputer -Filter {operatingsystem -like "*2008 R2*"} -Properties operatingsystem,ipv4address| select name, operatingsystem,ipv4address foreach($b in $a ){ $ping=Test-Connection -ComputerName $b.Name -Count 1 -Quiet if($ping){ $b.Name Invoke-Command -ComputerName $b.name { Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | Get-ItemProperty -name Version -EA 0 | Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} | Sort-Object version -Descending | Select-Object -ExpandProperty Version -First 1 $PSVersionTable.PSVersion.Major if($psv -lt 4){ Write-Host "WMF4 is not installed, do you want restart the server to install? y/n" #\\syd02\Syd_Transfer\yli\WMF4.bat $install=read-host switch($install) { "y"{ write-host "The Server is rebooting" #Restart-Computer -ComputerName $b.name -Force } "n"{ write-host ""} default {} } } Write-Host "" Write-Host "---------------------------------------------" } } }
大概效果如下,第一个是服务器名字,然后输出.net 版本和PS的版本,如果PS低于4,那么询问是否需要重启服务器以便安装。