今天早上接了个邮件,需要在所有的windows 2008R2的服务器上都安装 .net 4.5和 WMF4( PowerShell 4.0)。


豆子做了些研究,觉得需要做到以下几点

  1.  扫描所有的windows 2008 R2服务器,能够查看4.5和Powershell的当前版本是什么;

  2.  如果需要安装,必须以先安装.net 4.5, 然后安装WMF4的顺序进行,不然会出现安装显示正常,但是WMF4并未完全安装的问题。

  3. 安装的方式,可以采用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,那么询问是否需要重启服务器以便安装。


GPO 安装 .net 4.5和WMF4_第1张图片