Public/Set-PlexConfiguration.ps1

function Set-PlexConfiguration
{
    <#
        .SYNOPSIS
            Obtains an access token for your account and saves it and your server details.
        .DESCRIPTION
            Used to save Plex configuration to disk, which is used by all other functions.
        .PARAMETER Credential
            Credential object containing your Plex username and password.
        .EXAMPLE
            Set-PlexConfiguration -Credential (Get-Credential)
    #>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [PSCredential]
        $Credential,

        [Parameter(Mandatory = $true)]
        [String]
        $DefaultServerName
    )


    #Region Get auth token:
    try
    {
        $Base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password)))
        $Data = Invoke-RestMethod -Uri "https://plex.tv/users/sign_in.json" -Method POST -Headers @{
            'Authorization'            = ("Basic {0}" -f $Base64AuthInfo);
            'X-Plex-Client-Identifier' = "PowerShell-Test";
            'X-Plex-Product'           = 'PowerShell-Test';
            'X-Plex-Version'           = "V0.01";
            'X-Plex-Username'          = $Credential.GetNetworkCredential().UserName;
        } -ErrorAction Stop
    }
    catch
    {
        throw $_
    }
    #EndRegion

    #Region Get online servers
    try
    {
        $ResourceData = Invoke-RestMethod -Uri "https://plex.tv/api/v2/resources?includeHttps=1&X-Plex-Token=$($Data.user.authentication_token)&X-Plex-Client-Identifier=PSPlex" -Method GET -UseBasicParsing -Headers @{"Accept" = "application/json, text/plain, */*" }
        if(!$ResourceData)
        {
            throw "Could not get resource data."
        }

        # Refine to only servers that are online and owned by the user:
        [Array]$OwnedAndOnline = $ResourceData | Where-Object { $_.product -eq 'Plex Media Server' -and $_.owned -eq 1 }
        if(!$OwnedAndOnline)
        {
            throw "No owned servers online."
        }

        # If in the owned and online servers, there's no match for $DefaultServerName, throw an error:
        if($OwnedAndOnline.Name -notcontains $DefaultServerName)
        {
            throw "The server name '$DefaultServerName' does not match any of the owned and online servers."
        }

        # Loop and construct a custom object to store in our configuration file.
        $ConfigurationData = [System.Collections.ArrayList]@()
        foreach($Server in $OwnedAndOnline)
        {
            # When storing the configuration data for each server, we need an accessible uri.

            # In the .connections property there may be an array of objects each with an 'address' property.
            # Find an address where it's a public IP address and 'uri' matches 'plex.direct':
            $Connection = $Server.connections | Where-Object { $_.address -notmatch '(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)' -and $_.uri -match "plex.direct" }
            if(!$Connection)
            {
                # We didn't find a suitable Plex.direct connection to use so skip this server
                continue
            }

            # If the current server name is equal to $DefaultServerName, set the 'Default' property to $true
            if($Server.name -eq $DefaultServerName)
            {
                $Default = $true
            }
            else
            {
                $Default = $false
            }

            $ConfigurationData.Add(
                [PSCustomObject]@{
                    PlexServer       = $Server.name
                    Port             = $Connection.port
                    PublicAddress    = $Server.publicAddress
                    ClientIdentifier = $Server.clientIdentifier
                    Token            = $Server.accessToken
                    Uri              = $Connection.uri
                    Default          = $Default
                }) | Out-Null
        }
    }
    catch
    {
        throw $_
    }
    #EndRegion

    #Region Save Configuration to disk
    try
    {
        $ConfigFile = Get-PlexConfigFileLocation -ErrorAction Stop

        # Create folder if it doesn't exist:
        if(-not (Test-Path (Split-Path $ConfigFile)))
        {
            New-Item -ItemType Directory -Path (Split-Path $ConfigFile) | Out-Null
        }

        # Write the configuration data to disk:
        ConvertTo-Json -InputObject @($ConfigurationData) -Depth 3 -ErrorAction Stop | Out-File -FilePath $ConfigFile -Force -ErrorAction Stop
    }
    catch
    {
        throw $_
    }
    #EndRegion
}