-PSCustomToHashtable -InputObject $Member

					$Members += $Temp
				}

				$NextToken = $ParsedResponse.nextPageToken
				$Temp = "$Url&pageToken=$NextToken"
			}
			catch [System.Net.WebException]
			{
				$NextToken = $null

				[System.Net.WebException]$Ex = $_.Exception
				[System.Net.HttpWebResponse]$Response = [System.Net.HttpWebResponse]($Ex.Response)
				[System.IO.Stream]$Stream = $Ex.Response.GetResponseStream()
				[System.IO.StreamReader]$Reader = New-Object -TypeName System.IO.StreamReader($Stream, [System.Text.Encoding]::UTF8)
				[System.String]$Content = $Reader.ReadToEnd()
				[System.Int32]$StatusCode = $Response.StatusCode.value__
				[System.String]$Message = "$StatusCode : $Content"

				if ($ErrorActionPreference -eq [System.Management.Automation.ActionPreference]::Stop)
				{
					[System.Web.HttpException]$NewEx = New-Object -TypeName System.Web.HttpException($Content, $StatusCode)
					Write-Error -Exception $NewEx -Category NotSpecified -ErrorId $StatusCode
				}
				elseif ($ErrorActionPreference -ne [System.Management.Automation.ActionPreference]::SilentlyContinue)
				{
					Write-Warning -Message $Message
				}
				else
				{
					Write-Verbose -Message "[ERROR] : $Message"
				}
			}
			catch [Exception] 
			{
				$NextToken = $null

				if ($ErrorActionPreference -eq [System.Management.Automation.ActionPreference]::Stop)
				{
					Write-Error -Exception $_.Exception -ErrorAction Stop
				}
				elseif ($ErrorActionPreference -ne [System.Management.Automation.ActionPreference]::SilentlyContinue)
				{
					Write-Warning -Message $_.Exception.Message
				}
				else
				{
					Write-Verbose -Message "[ERROR] : $($_.Exception.Message)"
				}
			}
        } while ($NextToken -ne $null)

        Write-Output -InputObject $Members 
    }

    End {
    }
}

Function Remove-GoogleDirectoryGroupMember {
	<#
		.SYNOPSIS
			Removes a member from a GSuite group.

		.DESCRIPTION
			This cmdlet removes a member from a GSuite group.

		.PARAMETER GroupKey
			The unique Id of the group.

		.PARAMETER UserId
			The Id of the user to remove from the group.

		.PARAMETER BearerToken
			The bearer token to use to authenticate the request.

		.PARAMETER ClientId
			The client Id of the stored profile that contains the bearer token used to authenticate
			the request. The cmdlet will automatically update or refresh the access token if necessary (and is
			possible based on the other data stored in the profile).

		.PARAMETER ProfileLocation
			The location where stored credentials are located. If this is not specified, the default location will be used.

		.PARAMETER Persist
			Indicates that the newly retrieved token(s) or refreshed token and associated client data like client secret
			are persisted to disk.

		.EXAMPLE
			Remove-GoogleDirectoryGroupMember -GroupKey NNN -UserId <EMAIL> -ClientId $Id -Persist -UseCompression

			This example removes <EMAIL> from the group specified by NNN. The call is authenticated with an access 
			token stored in a client profile, which is refreshed if necessary. Any updated tokens are persisted to disk.

		.INPUTS 
			None
		
		.OUTPUTS
			None

		.NOTES
            AUTHOR: <NAME>
			LAST UPDATE: 2/12/2018
	#>
	[CmdletBinding()]
	[OutputType([System.Collections.Hashtable])]
	Param(
		[Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [System.String]$GroupKey,

		[Parameter(Mandatory = $true)]
		[ValidateNotNullOrEmpty()]
		[System.String]$UserId,

		[Parameter(Mandatory = $true, ParameterSetName = "Token")]
        [ValidateNotNullOrEmpty()]
        [System.String]$BearerToken,

		[Parameter(ParameterSetName = "Profile")]
		[System.String]$ProfileLocation,

		[Parameter(ParameterSetName = "Profile")]
		[Switch]$Persist
	)

	DynamicParam {
		New-DynamicParameter -Name "ClientId" -Type ([System.String]) -Mandatory -ParameterSets @("Profile") -ValidateNotNullOrEmpty -ValidateSet (Get-GoogleOAuth2Profile -ProfileLocation $ProfileLocation)
	}

	Begin {
	}

	Process {
		[System.String]$Base = $script:GroupBaseUrl

		if ($PSCmdlet.ParameterSetName -eq "Profile")
		{
			$ClientId = $PSBoundParameters["ClientId"]
			[System.Collections.Hashtable]$Token = Get-GoogleOAuth2Token -ClientId $ClientId -ProfileLocation $ProfileLocation -Persist:$Persist -ErrorAction Stop
			$BearerToken = $Token["access_token"]
		}

		[System.String]$Url = "$Base/$GroupKey/members/$UserId"

		try
		{
			[Microsoft.PowerShell.Commands.WebResponseObject]$Response = Invoke-WebRequest -Uri $Url -Method Delete -Headers @{"Authorization" = "Bearer $BearerToken"} -UserAgent PowerShell
		}
		catch [System.Net.WebException]
		{
			[System.Net.WebException]$Ex = $_.Exception
			[System.Net.HttpWebResponse]$Response = [System.Net.HttpWebResponse]($Ex.Response)
			[System.IO.Stream]$Stream = $Ex.Response.GetResponseStream()
			[System.IO.StreamReader]$Reader = New-Object -TypeName System.IO.StreamReader($Stream, [System.Text.Encoding]::UTF8)
			[System.String]$Content = $Reader.ReadToEnd()
			[System.Int32]$StatusCode = $Response.StatusCode.value__
			[System.String]$Message = "$StatusCode : $Content"

			if ($ErrorActionPreference -eq [System.Management.Automation.ActionPreference]::Stop)
			{
				[System.Web.HttpException]$NewEx = New-Object -TypeName System.Web.HttpException($Content, $StatusCode)
				Write-Error -Exception $NewEx -Category NotSpecified -ErrorId $StatusCode
			}
			elseif ($ErrorActionPreference -ne [System.Management.Automation.ActionPreference]::SilentlyContinue)
			{
				Write-Warning -Message $Message
			}
			else
			{
				Write-Verbose -Message "[ERROR] : $Message"
			}
		}
		catch [Exception] 
		{
			if ($ErrorActionPreference -eq [System.Management.Automation.ActionPreference]::Stop)
			{
				Write-Error -Exception $_.Exception -ErrorAction Stop
			}
			elseif ($ErrorActionPreference -ne [System.Management.Automation.ActionPreference]::SilentlyContinue)
			{
				Write-Warning -Message $_.Exception.Message
			}
			else
			{
				Write-Verbose -Message "[ERROR] : $($_.Exception.Message)"
			}
		}
	}

	End {
	}
}

#endregion

#region Users

Function New-GoogleDirectoryUser {
	<#
		.SYNOPSIS
			Creates a new GSuite user account.

		.DESCRIPTION
			This cmdlet creates a new user account.		

			- If the Google account has purchased mail licenses, the new user account is automatically assigned a mailbox. This assignment may take a few minutes to be completed and activated.
			- Editing a read-only field in a request, such as isAdmin, is silently ignored by the API service.
			- The maximum number of domains allowed in an account is 600 (1 primary domain + 599 additional domains)
			- If a user was not assigned to a specific organizational unit when the user account was created, the account is in the top-level organizational unit. A user's organizational unit determines which G Suite services the user has access to. If the user is moved to a new organization, the user's access changes. For more information about organization structures, see the administration help center.