0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

■ PowerShellでTailscale API ~コードでVPN管理したいよね?ね?~

Last updated at Posted at 2025-06-01

PowerShell_banner.png

こんにちは!
インフラもコードもハードも大好き、零壱(ゼロイチ)テクトです。

最近異様にハマっているOpenWrt弄りですが。
VPN接続するため、OpenWrtに限らずPCやスマホなどに
Tailscale」という、超絶簡単なのに超絶安心できるVPNアプリを
手持ちの端末にことごとくインストールしています。

インストールした台数が増えてきた為、NW情報を管理しようと思ったのですが
WEBページを見ながらポチポチとコピペで管理するのは面倒です。

調べたら「Tailscale API」があると分かったので
PowerShellでAPIにアクセスする勉強として
Tailscale APIで機器の情報を取得するコードを書きました。

1.概要/仕様

・事前にTailscaleのサイトにログインして
 「APIキーの発行」、「Tailnetのネットワーク名」をメモする事
・情報はCSV加工を前提に1つずつ取得する事
・「Exit Node」/「Subnet Router」も取得する事
・上記に伴いAPI URLで「fields=all」を付ける事
・Onlineステータスを取得できないので5分以内の接続をオンラインとする

2.事前準備

 ・Tailscaleを導入後の作業として扱うので、すでにアカウントはあるものとします。

  ■APIキー発行/取得

  ・Tailscaleの公式サイトにログインします。

    ●Tailscale公式:https://tailscale.com/

  ・ログイン後サイトのメニューの「Settings」をクリック

  

  ・「Settings」画面の左下「Keys」をクリック
  ・「Keys」画面の右下「API access tokens」の項目
  ・「Generate access token」ボタンをクリック

  

  ・API tokenのダイアログ表示される
  ・「Description」は適当なキーワードを入力
  ・「Expiration」でAPIの期限を入力

  

  ・「Generate access token」ボタンをクリック
  ・APIキーが表示されるので、無くさないようメモ

  ■ Tailnetネットワーク名取得

  ・TOPページのメニューから「DNS」をクリック
  ・「DNS」画面の「Tailnet name」にある、自身のネックワーク名をメモ

  

3.コード

TailscaleDeviceInfo.ps1
# ***** 設定値:APIキー/Tailnet名 *****
$tailscaleApiKey = "tskey-api-xxxxxxxxxxxxxxx" # Tailscale APIキー
$tailnetName     = "xxxxxxxxxxxxxxxxx.net"     # Tailnet名

# ***** APIエンドポイント *****
$apiUrl = "https://api.tailscale.com/api/v2/tailnet/$tailnetName/devices?fields=all"

# ***** APIリクエスト用ヘッダーの定義 *****
$headers = @{
    "Authorization" = "Bearer $tailscaleApiKey"
    "Accept"        = "application/json"
}

try {
    Write-Host "Tailscale APIからデバイス情報を取得中..." -ForegroundColor Cyan

    # APIへリクエスト送信/デバイス情報取得
    $response = Invoke-RestMethod -Uri $apiUrl -Method Get -Headers $headers -ContentType "application/json"
    $devices  = $response.devices

    # デバイス数が1以上で処理
    if ($devices.Count -gt 0) {
        
        # 各デバイスをループ処理し、情報を整形して表示
        $devices | ForEach-Object {

            # 変数にデバイスオブジェクトを代入
            $device = $_

            # ******** 各デバイスのステータス表示 ********
            Write-Host "----------------------------------"

            #現在時刻から最終アクセス時刻の差分計算
            $timeSinceLastSeen = (Get-Date) - [DateTime]$device.lastseen
    
            # オンライン閾値を設定:5分以下ならオンライン/5分以上ならオフライン
            # *TailscaleAPIでオンライン判定が無いため5分以内をオンラインとみなす
            if ($timeSinceLastSeen.TotalMinutes -lt 5) {
                Write-Host "Active: ● Online (Last: $($timeSinceLastSeen.TotalSeconds -as [int])Sec ago)" -ForegroundColor Green
            } else {
                Write-Host "Active: ✖ Offline " -ForegroundColor Red
            }

            # 各種取得デバイス情報
            Write-Host "LAST SEEN (UTC): $($device.lastseen) +9:00(JST)"
            Write-Host "hostname: $($device.hostname)"
            Write-Host "User: $($device.user)"
            Write-Host "Name: $($device.name)"
            Write-Host "TailscaleIP: $($device.addresses -join ', ')"
            Write-Host "OS: $($device.os)"
            Write-Host "clientVersion: $($device.clientVersion)"

            # Exit Node 有無判定
            if ($device.enabledRoutes) {
                Write-Host "[*] Exit Node" -ForegroundColor Yellow
                Write-Host "EnabledRoutes: $($device.enabledRoutes -join ', ')"
            }

            # Subnet Router 有無判定
            if ($device.advertisedRoutes) {
                Write-Host "[*] Subnet Router" -ForegroundColor Yellow
                Write-Host "Advertised Subnets: $($device.advertisedRoutes -join ', ')"
            }

        }
        Write-Host "----------------------------------"
    } else {
        # 取得デバイス数がゼロの場合
        Write-Host "------ デバイス情報なし" -ForegroundColor Yellow
    }

}
catch {

    # エラー処理
    Write-Host "API呼び出し中/エラー発生" -ForegroundColor Red
    Write-Host "エラーメッセージ: $($_.Exception.Message)" -ForegroundColor Red
    Write-Host "ステータスコード: $($_.Exception.Response.StatusCode.value__)" -ForegroundColor Red
    if ($_.Exception.Response) {
        Write-Host "詳細: $($_.Exception.Response.Content)" -ForegroundColor Red
    }
}

Write-Host "スクリプト終了------処理完了日時[$(Get-Date)]" -ForegroundColor Cyan

3.結果

 

 上記のように情報を取得できました。

4.備考

・✅ 改良案としては、これを弄るよりこのコードを定期的に実行して
   ステータスを監視して、それに応じて設定を変更したり
   一定期間で残ったデバイスを自動で削除するなり
   監視操作として発展させた方が良いと思いました。

・PowerShellでAPI接続して操作する方法は理解しました。

・全角文字を使ってますが、オンラインステータスを色分けしました。

・オンラインステータスは、本来WireGuardのセッションを考えると
 ほぼ数秒以内にアクセスできていればオンラインですが
 切れても接続を継続する仕組みを考えると、まあ5分ぐらいが妥当と思いました。

・情報は一つずつ取得できたので、必要に応じてCSVに変換できます。
 APIドキュメントにある情報は一通り取得可能です。

・今回は取得だけですが、デバイスの削除やACLなどもいじれるようです。

・削除は公式WEBサイトページをちゃんと見て削除したいので今回の処理では割愛。

5.参考/参照

■ Tailscale:API公式ドキュメント
https://tailscale.com/api#description/overview

■ Github/tailscale-client-go-v2
https://github.com/tailscale/tailscale-client-go-v2/blob/main/README.md
※GO言語によるTailscale APIの操作を網羅したコード集。感謝。


    それでは
         どこかの誰かの何かの足しになれば幸いです。
                     01000010 01011001 01000101

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?