Powershell:置換指定檔案

這次的任務是收到只是因為公司的小程式有很小幅度的變動,要更新指定的檔案。但是如果User沒有這個檔案就不做任何事情。這件事情因為只有影響少部分的人,所以就交給User自己手動執行檔案來做檢查/更新。

所以這程式的流程很容易。檢查檔案存不存在,存在就去Share server複製檔案過來蓋檔。但是我閒來無事就腦補一些功能,例如檢查檔案有有一致,還順便寫了Log紀錄一下使用狀況,同時也會輸出有顏色的文字來告知使用者成功與否。另外為了符合能多次使用,一開始就寫成丟參數的方式,想置換多個檔案就在同一個Batch裡面多執行幾次即可

下面是程式碼:

ReplaceFile.ps1

Param
(
    $Filename = "Nothing",#要置換的檔名
    $LocalFilePath = "Nothing",#本地端路徑
    $NewFilePath = "Nothing",#準備置換檔案的路徑
    $LogPath = "Nothing"#Log檔的位置
)
Get-Content $PSScriptRoot\GlobalVar.txt | Foreach-Object #尋找外部變數於GlobalVar.txt
{
    $var = $_.Split('=')
    New-Variable -Name $var[0] -Value $var[1]
 }
 $LogFile = Get-Date -Format yyyyMMdd
Function LogWrite
{
    Param([string]$logstring)
    [String]$Logfile = $LogPath+$LogFile+".txt" 
    Add-content $Logfile "$(Get-date -Format 'yyyy-MM-dd tthh:mm:ss') $logstring" 
}
function Write-Color([String[]]$Text, [ConsoleColor[]]$Color = "White", [int]$StartTab = 0, [int] $LinesBefore = 0,[int] $LinesAfter = 0, [string] $LogFile = "", $TimeFormat = "yyyy-MM-dd HH:mm:ss") 
{
    $DefaultColor = $Color[0]
    if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host "`n" -NoNewline } } # Add empty line before
    if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host "`t" -NoNewLine } } # Add TABS before text
    if ($Color.Count -ge $Text.Count) 
    {
        for ($i = 0; $i -lt $Text.Length; $i++) 
        { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
    }
    else
    {
        for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
        for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -NoNewLine }
    }
    Write-Host
    if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host "`n" } } # Add empty line after
    if ($LogFile -ne "")
    {
        $TextToFile = ""
        for ($i = 0; $i -lt $Text.Length; $i++) 
        {
            $TextToFile += $Text[$i]
        }
        Write-Output "[$([datetime]::Now.ToString($TimeFormat))]$TextToFile" | Out-File $LogFile -Encoding unicode -Append
    }
}
$FileExists = Test-path $LocalFilePath\$Filename
IF($Filename -eq "Nothing" -or $LocalFilePath -eq "Nothing" -or $NewFilePath -eq "Nothing")
{
    Write-Color -Text "Your Parameter is", " Nothing","." -Color Gray,Red,Gray
    LogWrite "$env:USERNAME@$env:COMPUTERNAME Parameter not exist"
    Exit
}
IF ($FileExists -eq $True)
{
    Copy-Item -path $NewFilePath\$Filename -Destination $LocalFilePath\ -Force

    Write-color "Your ","$Filename ", "has been update, please wait vertify...." -Color Gray,Yellow,Gray
    LogWrite "$env:USERNAME@$env:COMPUTERNAME $LocalFilePath\$Filename has been update, please wait vertify...." 
    $FileLocal = "$LocalFilePath\$Filename"
    $FileRemote = "$NewFilePath\$Filename"
    If((Get-FileHash $FileLocal).hash -eq (Get-FileHash $FileRemote).hash)
    {
        Write-Color "$FileLocal ","is ","SAME ","with ", "$Fileremote" -Color White,Gray,Green,Gray,White
        LogWrite "$env:USERNAME@$env:COMPUTERNAME $FileLocal is same with $Fileremote.Update successful."
    }
    Else
    {

        Write-Color "$FileLocal ","is ","NOT SAME ", "with ","$Fileremote",". Please contact with IT." -Color White,Gray,Red,Gray,White,Gray
        LogWrite "$env:USERNAME@$env:COMPUTERNAME $FileLocal is different with $Fileremote.Update Fail, Please contact with IT."  
    }
}
Else
{
    Write-Color "Your ","$Filename ", "is ", "NOT ", "update, Because, ","$Filename ", "isn't exists." -Color Gray,White,Gray,Red,Gray,White,Gray
    LogWrite "$env:USERNAME@$env:COMPUTERNAME $LocalFilePath\$Filename is NOT update,Because ini file isn't exists."
}

另外在裡面會呼叫TXT檔案裡的參數,預防萬一Share Server位置有變動我只要改外部的TXT檔就好了。

Globalvar.txt:放置在同一個目錄即可

FSRV_A=\\1.2.3.4
FSRV_B=\\1.2.3.5

Batch呼叫方式%FSRV_A。
Batch前面要加

for /f "delims== tokens=1,2" %%G in (%~dp0GlobalVar.txt) do set %%G=%%H

Powershell呼叫方式$FSRV_A
Powershell要加:

Get-Content $PSScriptRoot\GlobalVar.txt | Foreach-Object
{
    $var = $_.Split('=')
    New-Variable -Name $var[0] -Value $var[1]
}

使用Batch來呼叫ReplaceFile.ps1

ReplaceTest.bat

for /f "delims== tokens=1,2" %%G in (%~dp0GlobalVar.txt) do set %%G=%%H

Powershell %~dp0ReplaceFile.ps1 -Filename Test.ini LocalFilePath D:\ReplaceTest -NewFilePath %FSRV_A%\update\ReplaceFile -LogPath %FSRV_A%\share\IT\CSV_Log\ReplaceFile\Test

Powershell %~dp0ReplaceFile.ps1 -Filename Test1.ini -LocalFilePath D:\ReplaceTest -NewFilePath %FSRV_A%\update\ReplaceFile -LogPath %FSRV_A%\share\IT\CSV_Log\ReplaceFile\Test

Powershell %~dp0ReplaceFile.ps1 -Filename Test2.ini -LocalFilePath D:\ReplaceTest -NewFilePath %FSRV_A%\update\ReplaceFile -LogPath %FSRV_A%\share\IT\CSV_Log\ReplaceFile\Test
Pause

一行置換一個檔案,適合用來置換少量檔案且分散位置,還能確保檔案是否有置換成功,也能知道哪些人哪修電腦使用過。

下面是執行成果:

參數下錯或是缺少參數會呈現上述結果
正常成功會出現上述結果,至少都會看到綠色
這是為了示範複製完成後出現檔案驗證不過得狀態
(大概只有幾豪秒的機會,User在執行的時候你剛好把Server的檔案更新了才會造成檔案Hash比對失敗)
Log的生成,會有時間使用者電腦名稱以及文字敘述紀錄

至於顏色的寫法可以參考之前的另一篇

http://54.238.253.33/2018/03/31/powershell%e5%96%ae%e8%a1%8c%e8%bc%b8%e5%87%ba%e4%b8%8d%e5%90%8c%e9%a1%8f%e8%89%b2%e7%9a%84%e6%96%87%e5%ad%97/

以上感謝收看。