blog

テクノロジー|PowershellでLinux、macOS、Windowsのプロセスを自動化する

自動化はDevOpsの鍵ですが、何でも自動化できるのでしょうか?...

Nov 2, 2025 · 7 min. read
シェア

自動化はDevOpsの鍵ですが、何でも自動化できるのでしょうか?

自動化は、手作業で手間がかかり、ミスが発生しやすいプロセスを制御し、手作業を行うエンジニアを、自動化されたスクリプトを実行するコンピュータに置き換えます。手動プロセスが健全なDevOpsモデルの敵であることは誰もが認めるところです。自動化は勤勉なエンジニアに取って代わるため、良いことではないと考える人もいれば、一貫性、信頼性、効率性を向上させ、時間を節約し、エンジニアがスマートに作業できるようになると考える人もいます。

"DevOpsは単なる自動化やInfrastructure-as-Codeではない"

1980年代初頭に自動化されたプロセスやツールチェーンに取り組み始めて以来、「すべてを自動化せよ」というアドバイスを聞いたり読んだりすると、いつもわくわくしてきました。技術的にはすべてを自動化することは可能ですが、自動化は複雑で、開発、デバッグ、メンテナンスの面でコストがかかります。長い間使われていなかったAzureエクスプローラーのテンプレートや、ずっと前に書かれた貴重なメンテナンススクリプトを再アクティブ化し、数カ月後、数年後に完璧に動作することを期待したことがあるなら、他のコードと同様に自動化も壊れやすく、常にメンテナンスと育成が必要であることを知っているはずです。

では、いつ、何を自動化すればいいのでしょうか?

  • 自動化されたプロセスを手動で1~2回以上実行する場合
  • 自動化されたプロセスを頻繁かつ一貫して実行する必要がある場合
  • 自動化できるものは何でも自動化

さらに重要なのは、何を自動化すべきではないのか、ということです。

  • 非常に不安定なプロセスを自動化するのは、複雑でコストがかかりすぎるから。
  • 欠陥のあるプロセスは自動化せず、自動化する前に修正しましょう。

図1に示すように、これは技術的に難しいプロセスではありません。特に、コンテキストの実行中に他の開発作業や運用保守作業と切り替わる場合は、複雑でミスが起こりやすいプロセスです。

ちなみに、3つの簡単なステップで作成されたバリューストリームマップの例を以下に示します。

  1. ユーザーの一覧表示、ユーザーのフィルタリング、ライセンスのリセットなど、すべてのアクティビティを視覚化。
  2. 利害関係者(業務チームや認可チームなど)の特定。
  3. 対策
* 総配信時間= 13  
* トータル・サイクルタイム= 1.5  
* 総効率率= TLT/TCT*%

これらのビジュアライゼーションのコピーを、チームのディスカッションエリアや食堂、洗面所に向かう途中など、人の流れが多く、目につきやすい場所に掲示すれば、多くの議論が生まれ、積極的なフィードバックが得られるでしょう。例えば、視覚的に、手作業は時間の無駄であることは明らかで、そのほとんどはプロセスの待ち時間が長いことが原因です。

図2に示すように、このプロセスを自動化する簡単なPowerShellスクリプトを検証してみましょう。このスクリプトにより、配信時間の合計が13時間から4時間+60秒に短縮され、全体的な効率が11.5%から12.75%に向上します。

Donovan Brown オープンソースのタスクベースのスクリプト言語です。 GitHubに あります。PowerShellは、Linux、macOS、Windowsのプロセスを自動化することができます。開発のバックグラウンドを持つユーザー、特にC#ユーザーは、PowerShellのメリットを最大限に享受できます。

次のPowerShellスクリプトの例は、 PowerShell Service GitHub Azure DevOpsと 通信します。このスクリプトは、図 1 の手動の List Users タスクと Filter Users タスクを組み合わせて、デモ組織で 2 か月間非アクティブで、Basic ライセンスまたはより高価な Basic+Test ライセンスを使用しているすべてのユーザーを特定し、そのユーザーの詳細をコンソールに出力します。簡単です!

まず、認証ヘッダと、後の初期化スクリプトで使用するその他の変数を設定します:

  1. [string] $orgName = "DEMO",
  2. [int] $months = "-2",
  3. [string] $patToken = "<PAT>"
  4. # Basic authentication header using the personal access token (PAT)
  5. $basicAuth = ("{0}:{1}" -f "",$patToken)
  6. $basicAuth = [System.Text.Encoding]::UTF8.GetBytes($basicAuth)
  7. $basicAuth = [System.Convert]::ToBase64String($basicAuth)
  8. $headers = @{Authorization=("Basic {0}" -f $basicAuth)}
  9. # REST API Request to get all entitlements
  10. $request_GetEntitlements = 'https://...om/' + $orgName + '/_apis/userentitlements?top=10000&api-version=5.1-preview.2';
  11. # Initialize data variables
  12. $members = New-Object System.Collections.ArrayList
  13. [int] $count = 0;
  14. [string] $basic = "Basic";
  15. [string] $basicTest = "Basic + Test Plans";

次に、このスクリプトを使用してすべての権限を照会し、アクティブでないユーザーを特定します:

  1. # Send the REST API request and initialize the members array list.
  2. $response = Invoke-RestMethod -Uri $request_GetEntitlements -headers $headers -Method Get
  3. $response.items | ForEach-Object { $members.add($_.id) | out-null }
  4. # Iterate through all user entitlements
  5. $response.items | ForEach-Object {
  6. $name = [string]$_.user.displayName;
  7. $date = [DateTime]$_.lastAccessedDate;
  8. $expired = Get-Date;
  9. $expired = $expired.AddMonths($months);
  10. $license = [string]$_.accessLevel.AccountLicenseType;
  11. $licenseName = [string]$_.accessLevel.LicenseDisplayName;
  12. $count++;
  13. if ( $expired -gt $date ) {
  14. # Ignore users who have NEVER or NOT YET ACTIVATED their license
  15. if ( $date.Year -eq 1 ) {
  16. Write-Host " **INACTIVE** " " Name: " $name " Last Access: " $date "License: " $licenseName
  17. # Look for BASIC license
  18. elseif ( $licenseName -eq $basic ) {
  19. Write-Host " **INACTIVE** " " Name: " $name " Last Access: " $date "License: " $licenseName
  20. # Look for BASIC + TEST license
  21. elseif ( $licenseName -eq $basicTest ) {
  22. Write-Host " **INACTIVE** " " Name: " $name " Last Access: " $date "License: " $licenseName

スクリプトを実行すると、次のような出力が得られます。この出力をライセンスチームに転送して、ユーザーライセンスをリセットすることができます:

  1. **INACTIVE** Name: Demo1 Last Access: AM License: Basic
  2. **INACTIVE** Name: Demo2 Last Access: AM License: Basic
  3. **INACTIVE** Name: Demo3 Last Access: PM License: Basic
  4. **INACTIVE** Name: Demo4 Last Access: PM License: Basic
  5. **INACTIVE** Name: Demo5 Last Access: AM License: Basic
  6. **INACTIVE** Name: Demo6 Last Access: AM License: Basic
  7. **INACTIVE** Name: Demo7 Last Access: AM License: Basic
  8. **INACTIVE** Name: Demo8 Last Access: PM License: Basic + Test Plans
  9. **INACTIVE** Name: Demo9 Last Access: AM License: Basic

図3に示すように、ユーザーライセンスを無料のステークホルダーライセンスに自動的に設定することで最後のステップを自動化すると、全体の配信時間をさらに65秒に短縮し、全体の効率を77%に高めることができます。

この PowerShell スクリプトの中核的な価値は、実装できることだけでなく、このプロセスを実行できることにもあります。さらなる改善点としては、Azure Pipelineのようなスケジューラーを使用して、週単位または日単位でスクリプトをトリガーすることですが、プログラムによるライセンスのリセットとスクリプトのスケジューリングは、今後の投稿のために取っておきます。

このグラフは進捗状況を視覚化したものです:

Read next