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・Windows】どんな環境でもDropboxのルートディレクトリを確実に見つけ出す!堅牢な探索関数の作り方

Last updated at Posted at 2025-08-07

はじめに

PowerShellで定型業務を自動化する際、「Dropbox内のファイルにアクセスしたい」という場面は頻繁にあります。しかし、ユーザー名やインストール設定によって、PCごとにDropboxフォルダのパスは異なります。

スクリプト内にパスをハードコーディングするのは、メンテナンス性の悪さから避けたいところ。かといって、単純な方法ではMicrosoft Store版のDropboxや、変化する仕様に対応しきれません。

この記事では、試行錯誤の末にたどり着いた、どのような環境でもDropboxのパス(eg. C:Users\<username>\Dropbox%USERPROFILE%\Dropbox or D:\Dropbox etc.. )を確実に見つけ出す、堅牢なPowerShell関数 Find-DropboxPath の設計思想と、その完成版コードを紹介します。

この記事で目指すもの

  • 環境に依存しない: レジストリや設定ファイルなど、複数の情報源を探索し、あらゆる状況に対応する。
  • 信頼性の高い順に探索: OSの公式な情報から順に試すことで、処理の安定性を高める。
  • 自己完結した関数: どこにでも持ち運べる、ポータブルな関数として実装する。

完成したコード (Find-DropboxPath 関数)

まず、完成版の関数を以下に示します。

# -------------------------------------------------------------------
#
#   Find-DropboxPath: 複数方法でDropboxのルートフォルダパスを探索する
#
#   理由: PC環境やDropboxのバージョンによってパスの保存場所が異なるため、
#         複数の信頼性の高い場所を順番に探索し、スクリプトの堅牢性を高める。
#
# -------------------------------------------------------------------

function Find-DropboxPath {
    Write-Host "Dropboxのパスを3段階の優先順位で探索します..."
    
    # 方法1: Windows Cloud API レジストリ (最優先)
    # OSネイティブのクラウド連携機能で使われる公式な場所であり、最も信頼性が高い。
    try {
        $baseRegPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager'
        $userSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
        
        # SIDは正規表現で特別な意味を持つ文字を含む可能性があるため、安全に扱うためにエスケープする。
        $escapedSid = [regex]::Escape($userSid)
        $regexPattern = "^Dropbox!$($escapedSid)!dbid:.*"
        
        # Get-ChildItemでレジストリキーを取得すると、`.Name`プロパティにはフルパスが格納されてしまう。
        # キー自体の名前(例: 'Dropbox!S-1-5...')と比較するため、`.PSChildName`プロパティを使用する。
        $dropboxKey = Get-ChildItem -Path $baseRegPath -ErrorAction SilentlyContinue | Where-Object {
            $_.PSChildName -match $regexPattern
        } | Select-Object -First 1

        if ($dropboxKey) {
            # 発見したキーのパスを基準に、その子キーである`UserSyncRoots`のパスを組み立てる。
            $userSyncRootsKeyPath = Join-Path -Path $dropboxKey.PSPath -ChildPath "UserSyncRoots"

            if (Test-Path $userSyncRootsKeyPath) {
                # `UserSyncRoots`キーが持つプロパティの中から、名前が現在のユーザーSIDであるものの「値」を取得する。
                # これが目的のDropboxフォルダパスとなる。
                $pathValue = Get-ItemPropertyValue -Path $userSyncRootsKeyPath -Name $userSid -ErrorAction SilentlyContinue

                if ($pathValue -and (Test-Path $pathValue -PathType Container)) {
                    Write-Host "  [OK] 方法1 (Cloud APIレジストリ) からパスを発見しました。" -ForegroundColor Green
                    return $pathValue
                }
            }
        }
        Write-Host "  [NG] 方法1 (Cloud APIレジストリ) からは見つかりませんでした。" -ForegroundColor Gray
    } catch { Write-Host "  [NG] 方法1 (Cloud APIレジストリ) の探索に失敗しました。" -ForegroundColor Gray }

    # 方法2: Dropbox独自の構成ファイル (次善策)
    # アプリ固有の設定ファイル。仕様変更のリスクはあるが、多くの環境で有効なためバックアップとして探索する。
    try {
        $dbxJsonPath = "$env:LOCALAPPDATA\Dropbox\info.json"
        if (-not (Test-Path $dbxJsonPath)) { $dbxJsonPath = "$env:APPDATA\Dropbox\info.json" }
        if (Test-Path $dbxJsonPath) {
            $json = Get-Content $dbxJsonPath | ConvertFrom-Json
            # Null合体演算子(??)を使い、personalアカウントがなければbusinessアカウントのパスを試す。
            $jsonPath = $json.personal.path ?? $json.business.path
            if ($jsonPath) {
                Write-Host "  [OK] 方法2 (JSONファイル) からパスを発見しました。" -ForegroundColor Green
                return $jsonPath
            }
        }
        Write-Host "  [NG] 方法2 (JSONファイル) からは見つかりませんでした。" -ForegroundColor Gray
    } catch { Write-Host "  [NG] 方法2 (JSONファイル) の解析に失敗しました。" -ForegroundColor Gray }

    # 方法3: アプリケーション登録レジストリ (フォールバック)
    # Windowsにインストールされたアプリが自身の情報を登録する、従来からの標準的な場所。
    try {
        $regPath = (Get-ItemProperty -Path 'HKCU:\Software\Dropbox\Client' -Name 'install_path' -ErrorAction Stop).install_path
        if ($regPath) {
            Write-Host "  [OK] 方法3 (アプリ登録レジストリ) からパスを発見しました。" -ForegroundColor Green
            return $regPath
        }
    } catch { Write-Host "  [NG] 方法3 (アプリ登録レジストリ) からは見つかりませんでした。" -ForegroundColor Gray }

    return $null
}

設計思想 - なぜこの方法なのか?

この関数の核心は、複数の方法を階層的に試すという、フォールバックの考え方にあります。これは、目的地までのルートを複数知っている、優秀なカーナビのようなものです。

第1優先: Windows Cloud API レジストリ

  • Why: これはWindows OS自身が、エクスプローラーのサイドバー表示などのためにクラウドストレージを認識・管理する「公式」な記録です。DropboxがOSと連携している以上、この情報が最も正確で、将来にわたって安定している可能性が極めて高いと判断しました。

第2優先: Dropbox独自の構成ファイル (info.json)

  • Why: アプリケーション固有の設定ファイルです。アプリの仕様変更で場所や形式が変わるリスクはありますが、多くの環境で依然として有効なため、バックアップのルートとして確保しています。

第3優先: アプリケーション登録レジストリ

  • Why: OSにインストールされたアプリケーションが、自身のインストール場所などを登録する従来からの標準的な場所です。これも高い信頼性を持つため、第1の方法が何らかの理由で使えない場合の、強力な次善策となります。
  • ⚠️注意点⚠️: この方法は、主に公式サイトからダウンロードしたインストーラー(.exe形式)でインストールされた場合に有効です。Microsoft Storeからインストールされたアプリの場合、このレジストリキーは作成されないため、この探索は失敗します。

おわりに

PowerShellのスクリプトは、一度作って終わりではありません。様々な環境で、長く安定して動作するためには、今回のように複数の可能性を考慮した堅牢な設計が不可欠です。

単純なパス取得から始まったスクリプトも、デバッグと試行錯誤を重ねることで、最終的にこの信頼性の高い関数へとたどり着きました。

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?