30天挑戰精通 PowerShell 推薦序
時間先讓我回到2017年前後,那段時間有幾件技術正在發酵、發芽、成長。
- 當時有個火紅的技術產品叫 Docker,一下子讓全世界都跟瘋了一樣,每天大家都在談容器化(Containerization),我也不例外,開始接擉容器、學習容器、最後也順利導入容器。
- 拜 git 及 Github 所賜,分散式版控(Version Control)技術推廣大大突破,但只有控版還是無法解決「最後一哩」的問題。
- 第三個非常重要的概念及技術解決了「最後一哩」的問題,即C I/CD(Continuous Integration/Continuous Delivery(Deployment))。
- 從開發、版控、容器、CI/CD完成最後一哩持續自動化部屬,最後整合並成長為現在大家都知道的DevOps。
這裡面不論是封裝為 Docker 容器或是使用 git 的版控,還是由 CI/CD 成長成的 DevOps,我很高興都身在一個高度參與到這些技術發展與使用的團隊。而當初在實施整個 DevOps Pipeline (流水線)時,我們發現有個非常關鍵的技術並沒有出現在像上述火紅關鍵字之列,它就是指令碼(Script)或 CLI(Command-line interface)。我這樣形容,DevOps 工具本身或許有GUI可以給設操作設定,但真正在底層工作都一堆自動化的指令碼或 CLI。因此,我開始進入了指令碼與 CLI 的美好世界。
舉例來說,假設我們在開發 ASP.NET Core 應用程式時都會用的「建置(Build)」動作,請問你要如何整合到 DevOps Pipeline 之中呢?如果你只熟悉 Visual Studio 等 IDE 開發環境,你根本無從下手。但你如果熟 dotnet CLI 的運作,流程大概會是這樣:
dotnet new console -o consoleApp
dotnet build .\consoleApp\ --output .\consoleApp\build
dotnet .\consoleApp\build\consoleApp.dll
dotnet publish .\consoleApp\ -o .\consoleApp\publish -c release
dotnet build
會自動做dotnet restore
(+1)動作。
如果剛好你是 .NET 開發人員,蠻建議打開你的命令提示字元玩玩上面幾行指令,體驗一下不一樣的開發流程,並且這些指令與你的 IDE 開發環境並不衝突是可以相輔相成的。重點來了,下圖是一個我用 Azure DevOps 裡 ASP.NET Core 範本建立的 CI 流程,你對一下每一個 dotnet 圖示與上面的指令。
可以很清楚看到,假如你不懂 dotnet CLI,你要如何設計 ASP.NET Core 的 CI 流程?相反,假如你懂 dotnet CLI,那麼要設計 ASP.NET Core 的 CI 流程是不是易如反掌。假設應用程式都開發好了,但團隊決定要將應用程式進行容器化,那麼你懂 docker CLI 和不懂 docker CLI 的區別又出來了。我們先不說 docker CLI,我們先專心把要建置為映象檔(image)的 Dockerfile
給寫出來:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["demo/demo.csproj", "demo/"]
RUN dotnet restore "./demo/demo.csproj"
COPY . .
WORKDIR "/src/demo"
RUN dotnet build "./demo.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./demo.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "demo.dll"]
這是一個標準 ASP.NET Core 的 Dockerfile,先不管你懂不懂 Dockerfile 那些 FROM
之類的關鍵字,但有沒有發現,dotnet CLI 又出現了,而且十之八九又和我一開始的4(+1)行 dotnet CLI 一樣。接著就能把專案程式碼與 Dockerfile 送到 CI Server 去進行完整建置與發行的動作,這些動作...你沒猜錯,也是一堆指令碼。
CI 是如此,CD 更是如此。以我們的 CD 環境來說,有傳統 Windows IIS、Windows Service、Docker環境(又分 docker.exe 及 docker-compose.exe 執行環境)、Kubernetes 叢集環境,每一種你都必須撰寫對應的指令碼對目標伺服器進行部屬前的環境準備,專案應用程式部屬及最後啟動專案應用程式等作業。
撰文當下,剛好我在改一支 CD 部屬指令碼,裡面有個需求是這樣,我需要取得 Domain Name 裡 HostName,以下面為例,我需要拿到 blog
這個主機名稱。
# $Name 是PowerShell的變數
$DockerHost="blog.kkbruce.net"
用你習慣的程式語言想一下,你要花多久來處理來取得這個字串:
$HostName=$DockerHost.Split('.')[0];
對,你沒看錯 .Split('.')[0]
,我用的是 .NET(C#) 語法。這才是我想講的話,如果你懂 .NET(C#) 那麼學會 PowerShell 對你來說就是神兵利器,可以得到 1+1>2 的效果。你應該沒看過在 C# 裡寫 PowerShell,但在 PowerShell 裡面充滿了 .NET(C#)。並且現在的 PowerShell Core 在不呼叫到 Windows 專用 API 的情況下是可以跨平台執行的。
再舉一個實務維護應用的例子,當專案開發完成,你怎麼知道你的服務隨時都是正常的?並且時間越久,我們團隊想要監控的 Web 與 API 就越多?
# 讀取網頁清單
$WebList = (Import-Csv "$PSScriptRoot\WebUrls.csv").WebUrl
foreach ($url in $WebList) {
$result = Invoke-WebRequest -Uri $url -UseBasicParsing
if ($result.StatusCode -eq 200) {
Write-Host "`t $url connection StatusCode equals 200."
} else {
# 發送通知
Write-Error "`t $url connection StatusCode not equals 200."
}
}
這是簡化版監控 Web 的 PowerShell 指令碼,其實核心程式碼只有二行:一是讀取 CSV 的 Web 清單,二是發送一個 HTTP 請求確認狀態碼。監控 API 的程式碼也差不多。有新 服務,就往 CSV 加清單資料,簡單、免費、實用又有效。ASP.NET 的開發人員都知道, 早期 IIS 的 ASP.NET 專案在重新部署之後,第一次載入頁面會延遲較久的老問題。我們 一樣用類似上述的 PowerShell 指令碼,在部署完成後拿來當 Web 頁面預熱處理。甚至還 有大型 B2B API 資料交換的經驗,從連線 MS SQL 讀取資料、資料處理、資料序列化、 OAuth 驗證流程、POST JSON 到廠商 API 端點,從頭到尾全是用 PowerShell 來完成。
我用了那麼多篇幅說那麼多故事,就是想說,PowerShell 不只在 IT 工作上重要,在開 發及維護時也是非常好用。雖然作者強調,你不需要有任何 PowerShell 或 Bash 的經驗也 能學習,但 .NET(C# )的開發人員根本就是天生學習 PowerShell 的人材呀!你們擁有 IT 工程師所沒有的程式語言基礎,又比任何入門者熟悉底層的 .NET(C#),這會讓你們 在學習 PowerShell 這條路上走得又快又順又好。
回到正題。市面上針對 PowerShell 的中文書非常稀少,這是一本簡單易懂的入門 書,且作者規劃得很好,每天用一點時間學一點技巧,讓我們在很短的時間內,就能 把 PowerShell 的精髓學好。在未來的世界,可預見指令碼與 CLI 只會越來越重要,但如果只會打 dir
,就有點可惜了。利用本書,把 PowerShell 指令碼的基礎打好,從一行命 令開始,到一小段指令碼,再加入程式結構,後續慢慢改善整個指令碼的結構。此外, PowerShell 也有類似 C# 的 NuGet 的第三方函式庫,例如上述的 MS SQL 作業,就是利用 MS SQL 提供的 PowerShell 模組來完成的。再舉個例子,團隊碰過許多 FTP(SFTP )自 動化需求,單純用 .NET(C# )就很不好解決,但學會使用 PowerShell 之後,這類需求處 理起來真的是輕鬆又愉快。
我因為學習 PowerShell 而看到不一樣的世界,相信你學習 PowerShell 之後也能開闊你 的眼界。
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。