Search code examples
powershellflysystem-google-drive

Find the mapped google drive


If (!(Get-PSDrive R -PSProvider FileSystem -ErrorAction SilentlyContinue)) {
    #this function checks for the latest exe of google drive.  Then tries to start it.
    Import-Module C:\Tasks\Modules\Find-LatestFileVersion\Find-LatestFileVersion.psm1
    $GdfsPath = Find-LatestFileVersion -fileName "GoogleDriveFS.exe" -filePath "$Env:Programfiles\Google"
    Try {
        Start-Process $GdfsPath.FilePath | Wait-Process -Timeout 30
    }
    Catch {
        Write-Warning "Drive R to Google Drive can't be mapped. $Email failed to record seperation."

        $mailBody = "Drive R to Google Drive can't be mapped. $Email failed to record seperation."
        $mailSubject = "Drive R to Google Drive can't be mapped. $Email failed to record seperation."
       
        Send-MailMessage @MailArguments -to $ENV:BUILD_USER_EMAIL -Subject $mailSubject -Body $mailBody
        throw "Drive R to Google Drive can't be mapped. $Email failed to record seperation."
    }
    Finally {
        If (!(Get-PSDrive R -PSProvider FileSystem -ErrorAction SilentlyContinue)) {
            Write-Warning "Drive R to Google Drive can't be mapped. $Email failed to record seperation."

            $mailBody = "Drive R to Google Drive can't be mapped. $Email failed to record seperation."
            $mailSubject = "Drive R to Google Drive can't be mapped. $Email failed to record seperation."
           
            Send-MailMessage @MailArguments -to $ENV:BUILD_USER_EMAIL -Subject $mailSubject -Body $mailBody
            throw "Drive R to Google Drive can't be mapped. $Email failed to record seperation." 
        }
    }
}

Above tests if the drive is mapped. If not tries to start Google Drive and then tests again.

The big issue is the assumption that google drive is the R: drive. There does not seem to be a command line that will start google drive with a drive letter or a means to test if a drive letter is a google drive.

Thoughts?


Solution

  • I've found a solution. It looks like Google Drive for Desktop (formerly Drive File Stream) presents itself to the Operating System as a local disk, which means the remote capability is likely baked into the driver. While there are ways in PowerShell to trace the driver in use by a particular drive, there is a simpler solution:

    $googleDriveLetter = ( Get-PSDrive | Where-Object {
      $_.Description -eq 'Google Drive'
    } ).Name
    

    The Description is based on the Label property of Win32_Volume, but as long as an administrative user has not changed the drive label it should be Google Drive on a GD letter drive.

    This might not seem robust considering the drive label is easily changed, but there aren't really any other options I could find. The GD drive is a logical disk that has no physical backing, and no PNP device ID to reference to obtain a driver name. Interestingly enough, there don't seem to be any Google drivers related to Google Drive present on my system with GDD either. I'm not exactly sure how GDD mounts itself, as under the hood it looks like neither a physical or virtual disk.


    Apparently Google Drive looks like a local disk as far as PowerShell/Windows is concerned. The below won't work for this use case but is still useful in generally figuring out which mapped drives are network drives, and the mapping to specific servers or shares.

    Original answer

    You should be able see the drive mapping endpoint using:

    Get-PSDrive -PSProvider FileSystem | Select Name, Root
    

    Local drives will show their local path mountpoint as the Root (e.g. C: will show C:\, folder mounts will show the directory they are mounted in), but the remote endpoint should have a UNC path there. There should be something specific to Google for its root path. So once you know what the Google Drive root is, the drive letter will be the Name for the same PSDrive:

    $googleDriveLetter = ( Get-PSDrive -PSProvider FileSystem | Where-Object {
      $_.Root -match '^GOOGLE_DRIVE_ROOT_PREFIX'
    } ).Name
    

    The above uses a regular expression to search at the beginning of the value of Root, so just make sure you don't remove the caret ^ when replacing GOOGLE_DRIVE_ROOT_PREFIX with whatever that value is.


    Note that you will probably want to put the prefix through [regex]::Escape(string) prior to matching on it just to be safe, as UNC paths will almost always have special characters in them that regex uses:

    # This is not the GD prefix, just a regular UNC path example
    $driveRootPrefix = "\\server.domain.tld"
    $escapedPrefix = [regex]::Escape($driveRootPrefix)
    
    # In the Where-Object block
    $_.Root -match "^$escapedPrefix"