Powershell : 偵測Java版本並修改Bat檔/發送信件

會寫出這一段程式,是因為廠商的程式無法改變的情況下,我們只好自己動手了。
起因是,廠商寫了一個Bat檔案,他是用Java執行的,他的程式執行到某些功能會去呼叫這個bat去做某些動作,來看看這個bat(我修改某修路徑避免洩密之嫌)

@echo off

echo "PlugIn starting..."

call setenv.bat

"C:\Program Files (x86)\Java\jre1.8.0_181\bin\java.exe" -Xmx512m -DLogConfig=%LogConfig% -DSSL=N -cp %CLASSPATH% -Djava.library.path=%LIB_PATH% -Dfile.encoding=utf-8 com.XXXXXXXX.pl.hdl.PlugInHandler %1%

各位看倌有看到嗎?他把Java路徑寫死了。只要Java一升版(Java升版經由總部派送,User無法得知什麼ˊ時候被更新了),這隻程式就會立刻沒有用。之前做過一隻替換程式,當User發現程式無法執行出現特錯誤的時候,跑一隻我寫的檢查和更新程式,來把bat檔替換掉就可以了。

#讀取WMI物件的作業系統版本
#開頭為10的,為Windows10
#開頭為6的,為Window7
[String]$OS = ((Get-CimInstance win32_OperatingSystem).version).split(".",2)[-2]
[String]$Waitkey = "Job finish. Press Enter to exit:::"
[Bool]$CheckABC = Test-Path "D:\ABC\DEF\GHI\"
Switch($OS)
{
    10
        {
            Write-host "Your OperatingSystem is Windows 10 X64"
            $javaver= dir "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment"  | select -expa pschildname -Last 1
            $Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\$Javaver\" -Name JavaHome).JavaHome

        }
    6
        {
            Write-host "Your OperatingSystem is Windows 7 X86"
            $javaver= dir "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment"  | select -expa pschildname -Last 1
            $Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\$Javaver\" -Name JavaHome).JavaHome
        }
}
Write-Host "Your Java Version is $javaver"
Write-Host "Your Java path in $Javaexpath\bin"  
Write-Host "Replace your PlugInHandler.bat with PlugInHandler-$OS-$Javaver.bat."
IF($CheckABC -eq $True)
{
    Copy-Item -Path \\2.3.4.5\AAA\ D:\ABC\DEF\GHI\\PlugInHandler*.* -Destination D:\ABC\DEF\GHI\ -Force
    Copy-Item -Path D:\\ABC\DEF\GHI\PlugInHandler-$OS-$Javaver.bat -Destination D:\\ABC\DEF\GHI\PlugInHandler.bat -Force
}
Else
{
   Write-Host "You don't have ABC" 
}
Read-Host $Waitkey

稍微解釋一下,先判斷Windows 7 / 10,因為系統路徑不同
讀取機碼找到最新的Java安裝版本,然後根據系統版本找到預先做好對應版本的bat檔,直接替換檔案並更名。整隻其實只是判斷JRE的版本然後直接替換而已

所以也是要等User自己發現有問題再跑上來點。少了主動通知的功能。這次因為有一台無人值守的公用電腦,被總部派送Java更新之後,廠商的程式就故障了,故障之後連帶影響日常自動化作業,因此,必須另外寫一隻程式來偵測版本更新並且自動發Mail通知我們。
整個Powershell是會放在工作排程裡每30分鐘執行檢查一次,如有發現版本不對就立刻發送郵件到指定信箱,每天的九點不管正不正常都會發送一次通知Mail來得知排程有在正常運行。

$PlugInHanderPath = "D:\ACB\DEF\GHI\PlugInHandler.bat"                                                                                                 #檔案路徑
$PlugInHanderstring = Get-Content -Path $PlugInHanderPath | Where-Object { $_.Trim() -ne '' }                                                                    #讀取檔案內容去除空白
$PlugInHanderJvPath=$PlugInHanderString |select -Last 1 |%{$_.split('"')[1]}                                                                                     #讀取最末行找出路徑
$javaver= dir "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment"  | select -expa pschildname -Last 1
$Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\$Javaver\" -Name JavaHome).JavaHome + "\bin\java.exe"
$OS = gwmi win32_operatingsystem | Select -ExpandProperty Version
$SKU = gwmi win32_operatingsystem | Select -ExpandProperty OperatingSystemSKU
$min = Get-Date '09:00'
$max = Get-Date '09:30'
$now = Get-Date

$Sender = 'abc@def.com'
$RecipientAPM = 'abc@def.com'
$RecipientNor = 'abc@def.com'
$Subject = "Java version check."
$IP = Get-NetIPAddress | Where-Object -FilterScript { $_.ValidLifetime -Lt ([TimeSpan]::FromDays(1)) }| Select -ExpandProperty IPAddress

Switch ($SKU)
{
4
    {$Branchver = "CBB"}
125
    {$Branchver = "LTSB/C"}
}
#Write-host "Your PlusInHander Java Excution Path is "$PlugInHanderJvPath
#Write-host "Your PC Java Execuction Path is "$Javaexpath

$BodyAlert = "<HTML><HEAD><META http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" /><TITLE></TITLE></HEAD>"
$BodyAlert += "<BODY bgcolor=""#ffffff"" style=""font-family: Frutiger, Calibri, times; color: #000000""><P>"
$BodyAlert += "<img src=""https://connect.dhl.com/cmsmedia/ImageLibrary/DPDHL-GROUP-ITS-yellow-bar-600.png"" alt=""Deutsche Post DHL Group IT Services""><BR>"
$BodyAlert += "Hi DGF TW IT Teams<BR><BR>"
$BodyAlert += "<font color=red>Warning!</font><BR> GICHIQ PlugInHander batch file Java is different with system Java Enviorment.<BR>Please go to update.<BR>"
$BodyAlert += "<TABLE style=""background: #e5e5e5;font-weight: normal;font-family: Frutiger, Calibri, times;""><TR><TD>GICHIQ Java Excution Path :</TD><TD><font color=red>$PlugInHanderJvPath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>System Java Execuction Path :</TD><TD><font color=red>$Javaexpath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>Computer Name :</TD><TD>$env:COMPUTERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>OS Verserion :</TD><TD>Windows $OS $Branchver</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>Domain/Username :</TD><TD>$env:USERDOMAIN\$env:USERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>IP Address :</TD><TD>$IP</TD></TR></TABLE><BR>"
$BodyAlert += "Thank you.<BR><BR>"
$BodyAlert += "Your IT Team."

$BodyNormal = "<HTML><HEAD><META http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" /><TITLE></TITLE></HEAD>"
$BodyNormal += "<BODY bgcolor=""#ffffff"" style=""font-family: Frutiger, Calibri, times; color: #000000""><P>"
$BodyNormal += "<img src=""https://connect.dhl.com/cmsmedia/ImageLibrary/DPDHL-GROUP-ITS-yellow-bar-600.png"" alt=""Deutsche Post DHL Group IT Services""><BR>"
$BodyNormal += "Hi DGF TW IT Teams<BR><BR>"
$BodyNormal += "GICHIQ PlugInHander batch file Java is same with system Java Enviorment.<BR>"
$BodyNormal += "<TABLE style=""background: #e5e5e5;font-weight: normal;font-family: Frutiger, Calibri, times;""><TR><TD>GICHIQ Java Excution Path :</TD><TD><font color=red>$PlugInHanderJvPath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>System Java Execuction Path :</TD><TD><font color=red>$Javaexpath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>Computer Name :</TD><TD>$env:COMPUTERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>OS Verserion :</TD><TD>Windows $OS $Branchver</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>Domain/Username :</TD><TD>$env:USERDOMAIN\$env:USERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>IP Address :</TD><TD>$IP</TD></TR></TABLE><BR>"
$BodyNormal += "Thank you.<BR><BR>"
$BodyNormal += "Your IT Team."

If($PlugInHanderJvPath -ne $Javaexpath)
{
    [System.Windows.MessageBox]::Show('Java verson not match. Please update GICHIQ','GICHIQ Java version check','OK','Error')
    Send-MailMessage -From $Sender -To $RecipientAPM -Subject $Subject -SmtpServer KULDCCAS1.dhl.com -bodyashtml -Body $BodyAlert
}
ELSE
{
    [System.Windows.MessageBox]::Show('Java verson match.','GICHIQ Java version check','OK','Information')
    IF($min.TimeOfDay -le $now.TimeOfDay -and $max.TimeOfDay -ge $now.TimeOfDay)  #Send mail between 09:00-09:30 , Mail should be send on 09:00
    {
        Send-MailMessage -From $Sender -To $RecipientNor -Subject $Subject -SmtpServer KULDCCAS1.dhl.com -bodyashtml -Body $BodyNormal
    }

}

我來分段解釋一下

這三個只為了將上面的批次檔裡C:\Program Files (x86)\Java\jre1.8.0_181\bin\java.exe,抽取出來,準備跟系統的版本做比對。
由於這批次檔裡面有摻查一些空白,所以做法是讀出檔案內容之後,把多餘的前後空白和空白列Trim掉,然後利用這個”符號來做分段,取出第一段字也就是我要的路徑

$PlugInHanderPath = "D:\GICHIQ\GICEDI\PLUG-IN\PlugInHandler.bat"                                                                                                 
$PlugInHanderstring = Get-Content -Path $PlugInHanderPath | Where-Object { $_.Trim() -ne '' }           
$PlugInHanderJvPath=$PlugInHanderString |select -Last 1 |%{$_.split('"')[1]}

下面兩個利用讀取機碼的方式來判斷系統安裝最新的版本
然後組合字串來準備比對

$javaver= dir "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment"  | select -expa pschildname -Last 1
$Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\$Javaver\" -Name JavaHome).JavaHome + "\bin\java.exe"

下面兩個是抓取系統版本用的

$OS = gwmi win32_operatingsystem | Select -ExpandProperty Version
$SKU = gwmi win32_operatingsystem | Select -ExpandProperty OperatingSystemSKU

下面三個是準備判斷時間的,9:00-9:30之間才會發送正常報告

$min = Get-Date '09:00'
$max = Get-Date '09:30'
$now = Get-Date

下面是準備信件內容的變數
$sender : 送件者(同時是該台電腦的登入帳號所屬的Email)
$RecipientAPM : 有異常時要發給的對象
$RecipientNor : 正常時每天九點發送的對象
$Subject : 主旨
$IP取得這一台電腦的IP位址

$Sender = 'abc@def.com'
$RecipientAPM = @('aaa@def.com','bbb@def.com')
$RecipientNor = @('ccc@def.com','ddd@def.com')
$Subject = "Public PC Java version check."
$IP = Get-NetIPAddress | Where-Object -FilterScript { $_.ValidLifetime -Lt ([TimeSpan]::FromDays(1)) }| Select -ExpandProperty IPAddress

下面是準備判斷Windows是CBB/LTSB(C)版本,用於信件內容

Switch ($SKU)
{
4
    {$Branchver = "CBB"}
125
    {$Branchver = "LTSB/C"}
}

下面是警告信件的內容,HTML格式

$BodyAlert = "<HTML><HEAD><META http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" /><TITLE></TITLE></HEAD>"
$BodyAlert += "<BODY bgcolor=""#ffffff"" style=""font-family: Frutiger, Calibri, times; color: #000000""><P>"
$BodyAlert += "Hi DGF TW IT Teams<BR><BR>"
$BodyAlert += "<font color=red>Warning!</font><BR>PlugInHander batch file Java is <font color=red><b>different</b></font> with system Java Enviorment.<BR>Please go to update.<BR>"
$BodyAlert += "<TABLE style=""background: #e5e5e5;font-weight: normal;font-family: Frutiger, Calibri, times;""><TR><TD>Java Excution Path :</TD><TD><font color=red>$PlugInHanderJvPath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>System Java Execuction Path :</TD><TD><font color=red>$Javaexpath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>Computer Name :</TD><TD>$env:COMPUTERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>OS Verserion :</TD><TD>Windows $OS $Branchver</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>Domain/Username :</TD><TD>$env:USERDOMAIN\$env:USERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyAlert += "<TR><TD>IP Address :</TD><TD>$IP</TD></TR></TABLE><BR>"
$BodyAlert += "Thank you.<BR><BR>"
$BodyAlert += "Your IT Team."

下面是正常每日報告信的內容

$BodyNormal = "<HTML><HEAD><META http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" /><TITLE></TITLE></HEAD>"
$BodyNormal += "<BODY bgcolor=""#ffffff"" style=""font-family: Frutiger, Calibri, times; color: #000000""><P>"
$BodyNormal += "Hi DGF TW IT Teams<BR><BR>"
$BodyNormal += "GICHIQ PlugInHander batch file Java is <b>same</b> with system Java Enviorment.<BR>"
$BodyNormal += "<TABLE style=""background: #e5e5e5;font-weight: normal;font-family: Frutiger, Calibri, times;""><TR><TD>Java Excution Path :</TD><TD><font color=red>$PlugInHanderJvPath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>System Java Execuction Path :</TD><TD><font color=red>$Javaexpath</font></TD><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>Computer Name :</TD><TD>$env:COMPUTERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>OS Verserion :</TD><TD>Windows $OS $Branchver</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>Domain/Username :</TD><TD>$env:USERDOMAIN\$env:USERNAME</TD></TR><TR><TD></TD><TD></TD></TR>"
$BodyNormal += "<TR><TD>IP Address :</TD><TD>$IP</TD></TR></TABLE><BR>"
$BodyNormal += "Thank you.<BR><BR>"
$BodyNormal += "Your IT Team.

接著才是程式主體,
如果版本異常,直接發送信件。
版本正確而且時間落在9:00-9:30之間送發送一次報告

If($PlugInHanderJvPath -ne $Javaexpath)
{
    #[System.Windows.MessageBox]::Show('Java verson not match. Please update ABC','Java version check','OK','Error')
    Send-MailMessage -From $Sender -To $RecipientAPM -Subject $Subject -SmtpServer KULDCCAS1.dhl.com -bodyashtml -Body $BodyAlert -Priority High
}
ELSE
{
    #[System.Windows.MessageBox]::Show('Java verson match.','Java version check','OK','Information')
    IF($min.TimeOfDay -le $now.TimeOfDay -and $max.TimeOfDay -ge $now.TimeOfDay)  
    {
        Send-MailMessage -From $Sender -To $RecipientNor -Subject $Subject -SmtpServer KULDCCAS1.dhl.com -bodyashtml -Body $BodyNormal
    }

}

下面是版本正常的信件

下面是異常時發出的通知。同時在Outlook收到時,會看到前面有驚嘆號!

其實如果串上前面的更新程式,是可以做到全自動化的,偵測到版本變動時直接替換或用Set-Content方式去修改bat的內容。但是,到頭來說一句話,都全自動的話我們就失業了,,,,,,