GitHub.psm1
[Cmdletbinding()] param() $scriptName = $MyInvocation.MyCommand.Name Write-Verbose "[$scriptName] Importing subcomponents" #region - Data import Write-Verbose "[$scriptName] - [data] - Processing folder" $dataFolder = (Join-Path $PSScriptRoot 'data') Write-Verbose "[$scriptName] - [data] - [$dataFolder]" Get-ChildItem -Path "$dataFolder" -Recurse -Force -Include '*.psd1' -ErrorAction SilentlyContinue | ForEach-Object { Write-Verbose "[$scriptName] - [data] - [$($_.Name)] - Importing" New-Variable -Name $_.BaseName -Value (Import-PowerShellDataFile -Path $_.FullName) -Force Write-Verbose "[$scriptName] - [data] - [$($_.Name)] - Done" } Write-Verbose "[$scriptName] - [data] - Done" #endregion - Data import #region - From private Write-Verbose "[$scriptName] - [private] - Processing folder" #region - From private/Auth Write-Verbose "[$scriptName] - [private/Auth] - Processing folder" #region - From private/Auth/DeviceFlow Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow] - Processing folder" #region - From private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1 Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1] - Importing" function Invoke-GitHubDeviceFlowLogin { <# .SYNOPSIS Starts the GitHub Device Flow login process. .DESCRIPTION Starts the GitHub Device Flow login process. This will prompt the user to visit a URL and enter a code. .EXAMPLE Invoke-GitHubDeviceFlowLogin This will start the GitHub Device Flow login process. The user gets prompted to visit a URL and enter a code. .NOTES For more info about the Device Flow visit: https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app https://docs.github.com/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#device-flow #> [OutputType([void])] [CmdletBinding()] param( # The Client ID of the GitHub App. [Parameter(Mandatory)] [string] $ClientID, # The scope of the access token, when using OAuth authentication. # Provide the list of scopes as space-separated values. # For more information on scopes visit: # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps [Parameter()] [string] $Scope, # The refresh token to use for re-authentication. [Parameter()] [securestring] $RefreshToken ) do { if ($RefreshToken) { $tokenResponse = Wait-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken } else { $deviceCodeResponse = Request-GitHubDeviceCode -ClientID $ClientID -Scope $Scope $deviceCode = $deviceCodeResponse.device_code $interval = $deviceCodeResponse.interval $userCode = $deviceCodeResponse.user_code $verificationUri = $deviceCodeResponse.verification_uri Write-Host '! ' -ForegroundColor DarkYellow -NoNewline Write-Host "We added the code to your clipboard: [$userCode]" $userCode | Set-Clipboard Read-Host 'Press Enter to open github.com in your browser...' Start-Process $verificationUri $tokenResponse = Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval } } while ($tokenResponse.error) $tokenResponse } Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1] - Done" #endregion - From private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1 #region - From private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1 Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1] - Importing" function Request-GitHubAccessToken { <# .SYNOPSIS Request a GitHub token using the Device Flow. .DESCRIPTION Request a GitHub token using the Device Flow. This will poll the GitHub API until the user has entered the code. .EXAMPLE Request-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID This will poll the GitHub API until the user has entered the code. .NOTES For more info about the Device Flow visit: https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app #> [OutputType([PSCustomObject])] [CmdletBinding(DefaultParameterSetName = 'DeviceFlow')] param( # The Client ID of the GitHub App. [Parameter(Mandatory)] [string] $ClientID, # The 'device_code' used to request the access token. [Parameter( Mandatory, ParameterSetName = 'DeviceFlow' )] [string] $DeviceCode, # The refresh token used create a new access token. [Parameter( Mandatory, ParameterSetName = 'RefreshToken' )] [securestring] $RefreshToken ) $body = @{ 'client_id' = $ClientID } if ($PSBoundParameters.ContainsKey('RefreshToken')) { $body += @{ 'refresh_token' = (ConvertFrom-SecureString $RefreshToken -AsPlainText) 'grant_type' = 'refresh_token' } } if ($PSBoundParameters.ContainsKey('DeviceCode')) { $body += @{ 'device_code' = $DeviceCode 'grant_type' = 'urn:ietf:params:oauth:grant-type:device_code' } } $RESTParams = @{ Uri = 'https://github.com/login/oauth/access_token' Method = 'POST' Body = $body Headers = @{ 'Accept' = 'application/json' } } try { Write-Verbose ($RESTParams.GetEnumerator() | Out-String) $tokenResponse = Invoke-RestMethod @RESTParams -Verbose:$false Write-Verbose ($tokenResponse | ConvertTo-Json | Out-String) return $tokenResponse } catch { Write-Error $_ throw $_ } } Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1] - Done" #endregion - From private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1 #region - From private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1 Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1] - Importing" function Request-GitHubDeviceCode { <# .SYNOPSIS Request a GitHub Device Code. .DESCRIPTION Request a GitHub Device Code. .EXAMPLE Request-GitHubDeviceCode -ClientID $ClientID -Mode $Mode This will request a GitHub Device Code. .NOTES For more info about the Device Flow visit: https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app #> [OutputType([PSCustomObject])] [CmdletBinding()] param( # The Client ID of the GitHub App. [Parameter(Mandatory)] [string] $ClientID, # The scope of the access token, when using OAuth authentication. # Provide the list of scopes as space-separated values. # For more information on scopes visit: # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps [Parameter()] [string] $Scope = 'gist, read:org, repo, workflow' ) $headers = @{ Accept = 'application/json' } $body = @{ client_id = $ClientID scope = $Scope } $RESTParams = @{ Uri = 'https://github.com/login/device/code' Method = 'POST' Body = $body Headers = $headers } try { Write-Verbose ($RESTParams.GetEnumerator() | Out-String) $deviceCodeResponse = Invoke-RestMethod @RESTParams -Verbose:$false return $deviceCodeResponse } catch { Write-Error $_ throw $_ } } Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1] - Done" #endregion - From private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1 #region - From private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1 Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1] - Importing" function Test-GitHubAccessTokenRefreshRequired { <# .SYNOPSIS Test if the GitHub access token should be refreshed. .DESCRIPTION Test if the GitHub access token should be refreshed. .EXAMPLE Test-GitHubAccessTokenRefreshRequired This will test if the GitHub access token should be refreshed. #> [CmdletBinding()] param() $tokenType = Get-GitHubConfig -Name 'AccessTokenType' -ErrorAction SilentlyContinue if ($tokenType -ne 'ghu_*') { Write-Verbose "The access token is not a user token. No need to refresh." return $false } $tokenExpirationDate = Get-GitHubConfig -Name 'AccessTokenExpirationDate' -ErrorAction SilentlyContinue $currentDateTime = Get-Date $remainingDuration = [datetime]$tokenExpirationDate - $currentDateTime # If the remaining time is less that $script:Auth.AccessTokenGracePeriodInHours then the token should be refreshed $remainingDuration.TotalHours -lt $script:Auth.AccessTokenGracePeriodInHours } Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1] - Done" #endregion - From private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1 #region - From private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1 Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1] - Importing" function Wait-GitHubAccessToken { <# .SYNOPSIS Waits for the GitHub Device Flow to complete. .DESCRIPTION Waits for the GitHub Device Flow to complete. This will poll the GitHub API until the user has entered the code. .EXAMPLE Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval This will poll the GitHub API until the user has entered the code. .EXAMPLE Wait-GitHubAccessToken -Refresh -ClientID $ClientID .NOTES For more info about the Device Flow visit: https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app #> [OutputType([PSCustomObject])] [CmdletBinding(DefaultParameterSetName = 'DeviceFlow')] param( # The Client ID of the GitHub App. [Parameter(Mandatory)] [string] $ClientID, # The device code used to request the access token. [Parameter( Mandatory, ParameterSetName = 'DeviceFlow' )] [string] $DeviceCode, # The refresh token used to request a new access token. [Parameter( Mandatory, ParameterSetName = 'RefreshToken' )] [securestring] $RefreshToken, # The interval to wait between polling for the token. [Parameter()] [int] $Interval = 5 ) do { if ($RefreshToken) { $response = Request-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken } else { $response = Request-GitHubAccessToken -ClientID $ClientID -DeviceCode $DeviceCode } if ($response.error) { switch ($response.error) { 'authorization_pending' { # The user has not yet entered the code. # Wait, then poll again. Write-Verbose $response.error_description Start-Sleep -Seconds $interval continue } 'slow_down' { # The app polled too fast. # Wait for the interval plus 5 seconds, then poll again. Write-Verbose $response.error_description Start-Sleep -Seconds ($interval + 5) continue } 'expired_token' { # The 'device_code' expired, and the process needs to restart. Write-Error $response.error_description exit 1 } 'unsupported_grant_type' { # The 'grant_type' is not supported. Write-Error $response.error_description exit 1 } 'incorrect_client_credentials' { # The 'client_id' is not valid. Write-Error $response.error_description exit 1 } 'incorrect_device_code' { # The 'device_code' is not valid. Write-Error $response.error_description exit 2 } 'access_denied' { # The user cancelled the process. Stop polling. Write-Error $response.error_description exit 1 } 'device_flow_disabled' { # The GitHub App does not support the Device Flow. Write-Error $response.error_description exit 1 } default { # The response contains an access token. Stop polling. Write-Error 'Unknown error:' Write-Error $response.error Write-Error $response.error_description Write-Error $response.error_uri break } } } } until ($response.access_token) $response } Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1] - Done" #endregion - From private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1 Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow] - Done" #endregion - From private/Auth/DeviceFlow Write-Verbose "[$scriptName] - [private/Auth] - Done" #endregion - From private/Auth #region - From private/Config Write-Verbose "[$scriptName] - [private/Config] - Processing folder" #region - From private/Config/Initialize-SecretVault.ps1 Write-Verbose "[$scriptName] - [private/Config/Initialize-SecretVault.ps1] - Importing" #Requires -Version 7.0 #Requires -Modules Microsoft.PowerShell.SecretManagement #Requires -Modules Microsoft.PowerShell.SecretStore function Initialize-SecretVault { <# .SYNOPSIS Initialize a secret vault. .DESCRIPTION Initialize a secret vault. If the vault does not exist, it will be created. .EXAMPLE Initialize-SecretVault -Name 'SecretStore' -Type 'Microsoft.PowerShell.SecretStore' Initializes a secret vault named 'SecretStore' using the 'Microsoft.PowerShell.SecretStore' module. .NOTES For more information about secret vaults, see https://learn.microsoft.com/en-us/powershell/utility-modules/secretmanagement/overview?view=ps-modules #> [OutputType([void])] [CmdletBinding()] param ( # The name of the secret vault. [Parameter()] [string] $Name = 'SecretStore', # The type of the secret vault. [Parameter()] [Alias('ModuleName')] [string] $Type = 'Microsoft.PowerShell.SecretStore' ) $functionName = $MyInvocation.MyCommand.Name $vault = Get-SecretVault | Where-Object { $_.ModuleName -eq $Type } if (-not $vault) { Write-Verbose "[$functionName] - [$Type] - Registering" switch ($Type) { 'Microsoft.PowerShell.SecretStore' { $vaultParameters = @{ Authentication = 'None' PasswordTimeout = -1 Interaction = 'None' Scope = 'CurrentUser' WarningAction = 'SilentlyContinue' Confirm = $false Force = $true } Reset-SecretStore @vaultParameters } } Write-Verbose "[$functionName] - [$Type] - Done" } else { Write-Verbose "[$functionName] - [$Type] - already registered" } $secretStore = Get-SecretVault | Where-Object { $_.Name -eq $Name } if (-not $secretStore) { Write-Verbose "[$functionName] - [$Name] - Registering" $secretVault = @{ Name = $Name ModuleName = $Type DefaultVault = $true Description = 'SecretStore' } Register-SecretVault @secretVault Write-Verbose "[$functionName] - [$Name] - Done" } else { Write-Verbose "[$functionName] - [$Name] - already registered" } } Write-Verbose "[$scriptName] - [private/Config/Initialize-SecretVault.ps1] - Done" #endregion - From private/Config/Initialize-SecretVault.ps1 #region - From private/Config/Reset-GitHubConfig.ps1 Write-Verbose "[$scriptName] - [private/Config/Reset-GitHubConfig.ps1] - Importing" function Reset-GitHubConfig { <# .SYNOPSIS Reset the GitHub configuration. .DESCRIPTION Reset the GitHub configuration. Specific scopes can be reset by using the Scope parameter. .EXAMPLE Reset-GitHubConfig Resets the entire GitHub configuration. .EXAMPLE Reset-GitHubConfig -Scope 'Auth' Resets the Auth related variables of the GitHub configuration. #> [Alias('Reset-GHConfig')] [OutputType([void])] [CmdletBinding()] param( # Reset the GitHub configuration for a specific scope. [Parameter()] [ValidateSet('Auth', 'All')] [string] $Scope = 'All' ) Write-Verbose "Resetting GitHub configuration for scope '$Scope'..." switch ($Scope) { 'Auth' { $Settings = @{ AccessToken = [securestring]::new() AccessTokenExpirationDate = [datetime]::MinValue AccessTokenType = '' AuthType = '' DeviceFlowType = '' RefreshToken = [securestring]::new() RefreshTokenExpirationDate = [datetime]::MinValue Scope = '' } } 'All' { $Settings = @{ AccessToken = [securestring]::new() AccessTokenExpirationDate = [datetime]::MinValue AccessTokenType = '' ApiBaseUri = 'https://api.github.com' ApiVersion = '2022-11-28' AuthType = '' DeviceFlowType = '' Owner = '' RefreshToken = [securestring]::new() RefreshTokenExpirationDate = [datetime]::MinValue Repo = '' Scope = '' UserName = '' } } } Set-GitHubConfig @Settings } Write-Verbose "[$scriptName] - [private/Config/Reset-GitHubConfig.ps1] - Done" #endregion - From private/Config/Reset-GitHubConfig.ps1 Write-Verbose "[$scriptName] - [private/Config] - Done" #endregion - From private/Config #region - From private/Menu Write-Verbose "[$scriptName] - [private/Menu] - Processing folder" #region - From private/Menu/Invoke-DrawMenu.ps1 Write-Verbose "[$scriptName] - [private/Menu/Invoke-DrawMenu.ps1] - Importing" function Invoke-DrawMenu { ## supportfunction to the Menu function below param ( $menuItems, $menuPosition, $menuTitel ) $fcolor = $host.UI.RawUI.ForegroundColor $bcolor = $host.UI.RawUI.BackgroundColor $l = $menuItems.length + 1 Clear-Host $menuwidth = $menuTitel.length + 4 Write-Host "`t" -NoNewline Write-Host ('*' * $menuwidth) -fore $fcolor -back $bcolor Write-Host "`t" -NoNewline Write-Host "* $menuTitel *" -fore $fcolor -back $bcolor Write-Host "`t" -NoNewline Write-Host ('*' * $menuwidth) -fore $fcolor -back $bcolor Write-Host '' Write-Debug "L: $l MenuItems: $menuItems MenuPosition: $menuposition" for ($i = 0; $i -le $l; $i++) { Write-Host "`t" -NoNewline if ($i -eq $menuPosition) { Write-Host "$($menuItems[$i])" -fore $bcolor -back $fcolor } else { Write-Host "$($menuItems[$i])" -fore $fcolor -back $bcolor } } } Write-Verbose "[$scriptName] - [private/Menu/Invoke-DrawMenu.ps1] - Done" #endregion - From private/Menu/Invoke-DrawMenu.ps1 #region - From private/Menu/Invoke-Meny.ps1 Write-Verbose "[$scriptName] - [private/Menu/Invoke-Meny.ps1] - Importing" function Menu { ## Generate a small "DOS-like" menu. ## Choose a menuitem using up and down arrows, select by pressing ENTER param ( [array]$menuItems, $menuTitel = 'MENU' ) $vkeycode = 0 $pos = 0 Invoke-DrawMenu $menuItems $pos $menuTitel while ($vkeycode -ne 13) { $press = $host.ui.rawui.readkey('NoEcho,IncludeKeyDown') $vkeycode = $press.virtualkeycode Write-Host "$($press.character)" -NoNewline if ($vkeycode -eq 38) { $pos-- } if ($vkeycode -eq 40) { $pos++ } if ($pos -lt 0) { $pos = 0 } if ($pos -ge $menuItems.length) { $pos = $menuItems.length - 1 } Invoke-DrawMenu $menuItems $pos $menuTitel } $($menuItems[$pos]) } <# ? What account do you want to log into? [Use arrows to move, type to filter] > GitHub.com GitHub Enterprise Server #> Write-Verbose "[$scriptName] - [private/Menu/Invoke-Meny.ps1] - Done" #endregion - From private/Menu/Invoke-Meny.ps1 Write-Verbose "[$scriptName] - [private/Menu] - Done" #endregion - From private/Menu #region - From private/Organization Write-Verbose "[$scriptName] - [private/Organization] - Processing folder" #region - From private/Organization/Blocking Write-Verbose "[$scriptName] - [private/Organization/Blocking] - Processing folder" #region - From private/Organization/Blocking/Block-GitHubUserByOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Blocking/Block-GitHubUserByOrganization.ps1] - Importing" filter Block-GitHubUserByOrganization { <# .SYNOPSIS Block a user from an organization .DESCRIPTION Blocks the given user on behalf of the specified organization and returns a 204. If the organization cannot block the given user a 422 is returned. .EXAMPLE Block-GitHubUserByOrganization -OrganizationName 'github' -Username 'octocat' Blocks the user 'octocat' from the organization 'github'. Returns $true if successful, $false if not. .NOTES https://docs.github.com/rest/orgs/blocking#block-a-user-from-an-organization #> [OutputType([bool])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username ) $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/blocks/$Username" Method = 'PUT' } try { $null = (Invoke-GitHubAPI @inputObject) # Should we check if user is already blocked and return true if so? return $true } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 422) { return $false } else { Write-Error $_.Exception.Response throw $_ } } } Write-Verbose "[$scriptName] - [private/Organization/Blocking/Block-GitHubUserByOrganization.ps1] - Done" #endregion - From private/Organization/Blocking/Block-GitHubUserByOrganization.ps1 #region - From private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1] - Importing" filter Get-GitHubBlockedUserByOrganization { <# .SYNOPSIS List users blocked by an organization .DESCRIPTION List the users blocked by an organization. .EXAMPLE Get-GitHubBlockedUserByOrganization -OrganizationName 'github' Lists all users blocked by the organization `github`. .NOTES https://docs.github.com/rest/orgs/blocking#list-users-blocked-by-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/blocks" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1] - Done" #endregion - From private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1 #region - From private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1] - Importing" filter Test-GitHubBlockedUserByOrganization { <# .SYNOPSIS Check if a user is blocked by an organization .DESCRIPTION Returns a 204 if the given user is blocked by the given organization. Returns a 404 if the organization is not blocking the user, or if the user account has been identified as spam by GitHub. .EXAMPLE Test-GitHubBlockedUserByOrganization -OrganizationName 'PSModule' -Username 'octocat' Checks if the user `octocat` is blocked by the organization `PSModule`. Returns true if the user is blocked, false if not. .NOTES https://docs.github.com/rest/orgs/blocking#check-if-a-user-is-blocked-by-an-organization #> [OutputType([bool])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Username ) $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/blocks/$Username" Method = 'GET' } try { (Invoke-GitHubAPI @inputObject).StatusCode -eq 204 } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 404) { return $false } else { throw $_ } } } Write-Verbose "[$scriptName] - [private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1] - Done" #endregion - From private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1 #region - From private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1] - Importing" filter Unblock-GitHubUserByOrganization { <# .SYNOPSIS Unblock a user from an organization .DESCRIPTION Unblocks the given user on behalf of the specified organization. .EXAMPLE Unblock-GitHubUserByOrganization -OrganizationName 'github' -Username 'octocat' Unblocks the user 'octocat' from the organization 'github'. Returns $true if successful. .NOTES https://docs.github.com/rest/orgs/blocking#unblock-a-user-from-an-organization #> [OutputType([bool])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/blocks/$Username" Method = 'DELETE' } try { $null = (Invoke-GitHubAPI @inputObject) return $true } catch { Write-Error $_.Exception.Response throw $_ } } Write-Verbose "[$scriptName] - [private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1] - Done" #endregion - From private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Blocking] - Done" #endregion - From private/Organization/Blocking #region - From private/Organization/Get-GitHubAllOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubAllOrganization.ps1] - Importing" filter Get-GitHubAllOrganization { <# .SYNOPSIS List organizations .DESCRIPTION Lists all organizations, in the order that they were created on GitHub. **Note:** Pagination is powered exclusively by the `since` parameter. Use the [Link header](https://docs.github.com/rest/guides/using-pagination-in-the-rest-api#using-link-headers) to get the URL for the next page of organizations. .EXAMPLE Get-GitHubAllOrganization -Since 142951047 List organizations, starting with PSModule .NOTES https://docs.github.com/rest/orgs/orgs#list-organizations #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # A organization ID. Only return organizations with an ID greater than this ID. [Parameter()] [int] $Since = 0, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = @{ since = $Since per_page = $PerPage } $inputObject = @{ APIEndpoint = '/organizations' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubAllOrganization.ps1] - Done" #endregion - From private/Organization/Get-GitHubAllOrganization.ps1 #region - From private/Organization/Get-GitHubMyOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubMyOrganization.ps1] - Importing" filter Get-GitHubMyOrganization { <# .SYNOPSIS List organizations for the authenticated user .DESCRIPTION List organizations for the authenticated user. **OAuth scope requirements** This only lists organizations that your authorization allows you to operate on in some way (e.g., you can list teams with `read:org` scope, you can publicize your organization membership with `user` scope, etc.). Therefore, this API requires at least `user` or `read:org` scope. OAuth requests with insufficient scope receive a `403 Forbidden` response. .EXAMPLE Get-GitHubMyOrganization List organizations for the authenticated user. .NOTES https://docs.github.com/rest/orgs/orgs#list-organizations-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = '/user/orgs' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubMyOrganization.ps1] - Done" #endregion - From private/Organization/Get-GitHubMyOrganization.ps1 #region - From private/Organization/Get-GitHubOrganizationByName.ps1 Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubOrganizationByName.ps1] - Importing" filter Get-GitHubOrganizationByName { <# .SYNOPSIS Get an organization .DESCRIPTION To see many of the organization response values, you need to be an authenticated organization owner with the `admin:org` scope. When the value of `two_factor_requirement_enabled` is `true`, the organization requires all members, billing managers, and outside collaborators to enable [two-factor authentication](https://docs.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/). GitHub Apps with the `Organization plan` permission can use this endpoint to retrieve information about an organization's GitHub plan. See "[Authenticating with GitHub Apps](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/)" for details. For an example response, see 'Response with GitHub plan information' below." .EXAMPLE Get-GitHubOrganizationByName -OrganizationName 'github' Get the 'GitHub' organization .NOTES https://docs.github.com/rest/orgs/orgs#get-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [Alias('org')] [Alias('owner')] [string] $OrganizationName ) $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubOrganizationByName.ps1] - Done" #endregion - From private/Organization/Get-GitHubOrganizationByName.ps1 #region - From private/Organization/Get-GitHubUserOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubUserOrganization.ps1] - Importing" filter Get-GitHubUserOrganization { <# .SYNOPSIS List organizations for a user .DESCRIPTION List [public organization memberships](https://docs.github.com/articles/publicizing-or-concealing-organization-membership) for the specified user. This method only lists _public_ memberships, regardless of authentication. If you need to fetch all of the organization memberships (public and private) for the authenticated user, use the [List organizations for the authenticated user](https://docs.github.com/rest/orgs/orgs#list-organizations-for-the-authenticated-user) API instead. .EXAMPLE Get-GitHubUserOrganization -Username 'octocat' List public organizations for the user 'octocat'. .NOTES https://docs.github.com/rest/orgs/orgs#list-organizations-for-a-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter(Mandatory)] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/users/$Username/orgs" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubUserOrganization.ps1] - Done" #endregion - From private/Organization/Get-GitHubUserOrganization.ps1 Write-Verbose "[$scriptName] - [private/Organization] - Done" #endregion - From private/Organization #region - From private/Users Write-Verbose "[$scriptName] - [private/Users] - Processing folder" #region - From private/Users/Blocking Write-Verbose "[$scriptName] - [private/Users/Blocking] - Processing folder" #region - From private/Users/Blocking/Block-GitHubUserByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Blocking/Block-GitHubUserByUser.ps1] - Importing" filter Block-GitHubUserByUser { <# .SYNOPSIS Block a user .DESCRIPTION Blocks the given user and returns a 204. If the authenticated user cannot block the given user a 422 is returned. .EXAMPLE Block-GitHubUserByUser -Username 'octocat' Blocks the user 'octocat' for the authenticated user. Returns $true if successful, $false if not. .NOTES https://docs.github.com/rest/users/blocking#block-a-user #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/blocks/$Username" Method = 'PUT' } try { $null = (Invoke-GitHubAPI @inputObject) # Should we check if user is already blocked and return true if so? return $true } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 422) { return $false } else { Write-Error $_.Exception.Response throw $_ } } } Write-Verbose "[$scriptName] - [private/Users/Blocking/Block-GitHubUserByUser.ps1] - Done" #endregion - From private/Users/Blocking/Block-GitHubUserByUser.ps1 #region - From private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1] - Importing" filter Get-GitHubBlockedUserByUser { <# .SYNOPSIS List users blocked by the authenticated user .DESCRIPTION List the users you've blocked on your personal account. .EXAMPLE Get-GitHubBlockedUserByUser Returns a list of users blocked by the authenticated user. .NOTES https://docs.github.com/rest/users/blocking#list-users-blocked-by-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/blocks" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1] - Done" #endregion - From private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1 #region - From private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1] - Importing" filter Test-GitHubBlockedUserByUser { <# .SYNOPSIS Check if a user is blocked by the authenticated user .DESCRIPTION Returns a 204 if the given user is blocked by the authenticated user. Returns a 404 if the given user is not blocked by the authenticated user, or if the given user account has been identified as spam by GitHub. .EXAMPLE Test-GitHubBlockedUserByUser -Username 'octocat' Checks if the user `octocat` is blocked by the authenticated user. Returns true if the user is blocked, false if not. .NOTES https://docs.github.com/rest/users/blocking#check-if-a-user-is-blocked-by-the-authenticated-user #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/blocks/$Username" Method = 'GET' Body = $body } try { (Invoke-GitHubAPI @inputObject).StatusCode -eq 204 } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 404) { return $false } else { throw $_ } } } Write-Verbose "[$scriptName] - [private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1] - Done" #endregion - From private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1 #region - From private/Users/Blocking/Unblock-GitHubUserByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Blocking/Unblock-GitHubUserByUser.ps1] - Importing" filter Unblock-GitHubUserByUser { <# .SYNOPSIS Unblock a user .DESCRIPTION Unblocks the given user and returns a 204. .EXAMPLE Unblock-GitHubUserByUser -Username 'octocat' Unblocks the user 'octocat' for the authenticated user. Returns $true if successful. .NOTES https://docs.github.com/rest/users/blocking#unblock-a-user #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/blocks/$Username" Method = 'DELETE' } try { $null = (Invoke-GitHubAPI @inputObject) return $true } catch { Write-Error $_.Exception.Response throw $_ } } Write-Verbose "[$scriptName] - [private/Users/Blocking/Unblock-GitHubUserByUser.ps1] - Done" #endregion - From private/Users/Blocking/Unblock-GitHubUserByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Blocking] - Done" #endregion - From private/Users/Blocking #region - From private/Users/Emails Write-Verbose "[$scriptName] - [private/Users/Emails] - Processing folder" #region - From private/Users/Emails/Get-GitHubUserAllEmail.ps1 Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserAllEmail.ps1] - Importing" filter Get-GitHubUserAllEmail { <# .SYNOPSIS List email addresses for the authenticated user .DESCRIPTION Lists all of your email addresses, and specifies which one is visible to the public. This endpoint is accessible with the `user:email` scope. .EXAMPLE Get-GitHubUserAllEmail Gets all email addresses for the authenticated user. .NOTES https://docs.github.com/rest/users/emails#list-email-addresses-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/emails" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserAllEmail.ps1] - Done" #endregion - From private/Users/Emails/Get-GitHubUserAllEmail.ps1 #region - From private/Users/Emails/Get-GitHubUserPublicEmail.ps1 Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserPublicEmail.ps1] - Importing" filter Get-GitHubUserPublicEmail { <# .SYNOPSIS List public email addresses for the authenticated user .DESCRIPTION Lists your publicly visible email address, which you can set with the [Set primary email visibility for the authenticated user](https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user) endpoint. This endpoint is accessible with the `user:email` scope. .EXAMPLE Get-GitHubUserPublicEmail Gets all public email addresses for the authenticated user. .NOTES https://docs.github.com/rest/users/emails#list-public-email-addresses-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/public_emails" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserPublicEmail.ps1] - Done" #endregion - From private/Users/Emails/Get-GitHubUserPublicEmail.ps1 Write-Verbose "[$scriptName] - [private/Users/Emails] - Done" #endregion - From private/Users/Emails #region - From private/Users/Followers Write-Verbose "[$scriptName] - [private/Users/Followers] - Processing folder" #region - From private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1] - Importing" filter Get-GitHubUserFollowersOfUser { <# .SYNOPSIS List followers of a user .DESCRIPTION Lists the people following the specified user. .EXAMPLE Get-GitHubUserFollowersOfUser -Username 'octocat' Gets all followers of user 'octocat'. .NOTES https://docs.github.com/rest/users/followers#list-followers-of-a-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntries -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/followers" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1] - Done" #endregion - From private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1 #region - From private/Users/Followers/Get-GitHubUserFollowingMe.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingMe.ps1] - Importing" filter Get-GitHubUserFollowingMe { <# .SYNOPSIS List the people the authenticated user follows .DESCRIPTION Lists the people who the authenticated user follows. .EXAMPLE Get-GitHubUserFollowingMe Gets all people the authenticated user follows. .NOTES https://docs.github.com/rest/users/followers#list-the-people-the-authenticated-user-follows #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/following' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingMe.ps1] - Done" #endregion - From private/Users/Followers/Get-GitHubUserFollowingMe.ps1 #region - From private/Users/Followers/Get-GitHubUserFollowingUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingUser.ps1] - Importing" filter Get-GitHubUserFollowingUser { <# .SYNOPSIS List the people a user follows .DESCRIPTION Lists the people who the specified user follows. .EXAMPLE Get-GitHubUserFollowingUser -Username 'octocat' Gets all people that 'octocat' follows. .NOTES https://docs.github.com/rest/users/followers#list-the-people-a-user-follows #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntries -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/following" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingUser.ps1] - Done" #endregion - From private/Users/Followers/Get-GitHubUserFollowingUser.ps1 #region - From private/Users/Followers/Get-GitHubUserMyFollowers.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserMyFollowers.ps1] - Importing" filter Get-GitHubUserMyFollowers { <# .SYNOPSIS List followers of the authenticated user .DESCRIPTION Lists the people following the authenticated user. .EXAMPLE Get-GitHubUserMyFollowers Gets all followers of the authenticated user. .NOTES https://docs.github.com/rest/users/followers#list-followers-of-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/followers' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserMyFollowers.ps1] - Done" #endregion - From private/Users/Followers/Get-GitHubUserMyFollowers.ps1 #region - From private/Users/Followers/Test-GitHubUserFollowedByMe.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByMe.ps1] - Importing" filter Test-GitHubUserFollowedByMe { <# .SYNOPSIS Check if a person is followed by the authenticated user .DESCRIPTION Returns a 204 if the given user is followed by the authenticated user. Returns a 404 if the user is not followed by the authenticated user. .EXAMPLE Test-GitHubUserFollowedByMe -Username 'octocat' Checks if the authenticated user follows the user 'octocat'. .NOTES https://docs.github.com/rest/users/followers#check-if-a-person-is-followed-by-the-authenticated-user #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/following/$Username" Method = 'GET' } try { $null = (Invoke-GitHubAPI @inputObject) return $true } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 404) { return $false } else { throw $_ } } } Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByMe.ps1] - Done" #endregion - From private/Users/Followers/Test-GitHubUserFollowedByMe.ps1 #region - From private/Users/Followers/Test-GitHubUserFollowedByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByUser.ps1] - Importing" filter Test-GitHubUserFollowedByUser { <# .SYNOPSIS Check if a user follows another user .DESCRIPTION Checks if a user follows another user. .EXAMPLE Test-GitHubUserFollowedByUser -Username 'octocat' -Follows 'ratstallion' Checks if the user 'octocat' follows the user 'ratstallion'. .NOTES https://docs.github.com/rest/users/followers#check-if-a-user-follows-another-user #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Username, # The handle for the GitHub user account we want to check if user specified by $Username is following. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Follows ) $inputObject = @{ APIEndpoint = "/users/$Username/following/$Follows" Method = 'GET' } try { $null = (Invoke-GitHubAPI @inputObject) return $true } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 404) { return $false } else { throw $_ } } } Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByUser.ps1] - Done" #endregion - From private/Users/Followers/Test-GitHubUserFollowedByUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Followers] - Done" #endregion - From private/Users/Followers #region - From private/Users/GPG-Keys Write-Verbose "[$scriptName] - [private/Users/GPG-Keys] - Processing folder" #region - From private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1 Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1] - Importing" filter Get-GitHubUserGpgKeyForUser { <# .SYNOPSIS List GPG keys for a user .DESCRIPTION Lists the GPG keys for a user. This information is accessible by anyone. .EXAMPLE Get-GitHubUserGpgKeyForUser -Username 'octocat' Gets all GPG keys for the 'octocat' user. .NOTES https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-a-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntries -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/gpg_keys" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1] - Done" #endregion - From private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1 #region - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1 Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1] - Importing" filter Get-GitHubUserMyGpgKey { <# .SYNOPSIS List GPG keys for the authenticated user .DESCRIPTION Lists the current user's GPG keys. Requires that you are authenticated via Basic Auth or via OAuth with at least `read:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Get-GitHubUserMyGpgKey Gets all GPG keys for the authenticated user. .NOTES https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/gpg_keys' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1] - Done" #endregion - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1 #region - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1 Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1] - Importing" filter Get-GitHubUserMyGpgKeyById { <# .SYNOPSIS Get a GPG key for the authenticated user .DESCRIPTION View extended details for a single GPG key. Requires that you are authenticated via Basic Auth or via OAuth with at least `read:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Get-GitHubUserMyGpgKeyById -GpgKeyID '4AEE18F83AFDEB23' Gets the GPG key with ID '4AEE18F83AFDEB23' for the authenticated user. .NOTES https://docs.github.com/rest/users/gpg-keys#get-a-gpg-key-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The ID of the GPG key. [Parameter( Mandatory )] [Alias('gpg_key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/gpg_keys/$ID" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1] - Done" #endregion - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1 Write-Verbose "[$scriptName] - [private/Users/GPG-Keys] - Done" #endregion - From private/Users/GPG-Keys #region - From private/Users/Social-Accounts Write-Verbose "[$scriptName] - [private/Users/Social-Accounts] - Processing folder" #region - From private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1 Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1] - Importing" filter Get-GitHubMyUserSocials { <# .SYNOPSIS List social accounts for the authenticated user .DESCRIPTION Lists all of your social accounts. .EXAMPLE Get-GitHubMyUserSocials Lists all of your social accounts. .NOTES https://docs.github.com/rest/users/social-accounts#list-social-accounts-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/social_accounts' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1] - Done" #endregion - From private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1 #region - From private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1 Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1] - Importing" filter Get-GitHubUserSocialsByName { <# .SYNOPSIS List social accounts for a user .DESCRIPTION Lists social media accounts for a user. This endpoint is accessible by anyone. .EXAMPLE Get-GitHubUserSocialsByName -Username 'octocat' Lists social media accounts for the user 'octocat'. .NOTES https://docs.github.com/rest/users/social-accounts#list-social-accounts-for-a-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username ) $inputObject = @{ APIEndpoint = "/users/$Username/social_accounts" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1] - Done" #endregion - From private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1 Write-Verbose "[$scriptName] - [private/Users/Social-Accounts] - Done" #endregion - From private/Users/Social-Accounts #region - From private/Users/Get-GitHubAllUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Get-GitHubAllUser.ps1] - Importing" filter Get-GitHubAllUser { <# .SYNOPSIS List users .DESCRIPTION Lists all users, in the order that they signed up on GitHub. This list includes personal user accounts and organization accounts. Note: Pagination is powered exclusively by the `since` parameter. Use the [Link header](https://docs.github.com/rest/guides/using-pagination-in-the-rest-api#using-link-headers) to get the URL for the next page of users. .EXAMPLE Get-GitHubAllUser -Since 17722253 Get a list of users, starting with the user 'MariusStorhaug'. .NOTES https://docs.github.com/rest/users/users#list-users #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # A user ID. Only return users with an ID greater than this ID. [Parameter()] [int] $Since = 0, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/users" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Get-GitHubAllUser.ps1] - Done" #endregion - From private/Users/Get-GitHubAllUser.ps1 #region - From private/Users/Get-GitHubMyUser.ps1 Write-Verbose "[$scriptName] - [private/Users/Get-GitHubMyUser.ps1] - Importing" filter Get-GitHubMyUser { <# .SYNOPSIS Get the authenticated user .DESCRIPTION If the authenticated user is authenticated with an OAuth token with the `user` scope, then the response lists public and private profile information. If the authenticated user is authenticated through OAuth without the `user` scope, then the response lists only public profile information. .EXAMPLE Get-GitHubMyUser Get the authenticated user .NOTES https://docs.github.com/rest/users/users#get-the-authenticated-user #> [OutputType([pscustomobject])] [Alias('Get-GitHubContext')] [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/user' Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Get-GitHubMyUser.ps1] - Done" #endregion - From private/Users/Get-GitHubMyUser.ps1 #region - From private/Users/Get-GitHubUserByName.ps1 Write-Verbose "[$scriptName] - [private/Users/Get-GitHubUserByName.ps1] - Importing" filter Get-GitHubUserByName { <# .SYNOPSIS Get a user .DESCRIPTION Provides publicly available information about someone with a GitHub account. GitHub Apps with the `Plan` user permission can use this endpoint to retrieve information about a user's GitHub plan. The GitHub App must be authenticated as a user. See "[Identifying and authorizing users for GitHub Apps](https://docs.github.com/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps/)" for details about authentication. For an example response, see 'Response with GitHub plan information' below" The `email` key in the following response is the publicly visible email address from your GitHub [profile page](https://github.com/settings/profile). When setting up your profile, you can select a primary email address to be ΓǣpublicΓǥ which provides an email entry for this endpoint. If you do not set a public email address for `email`, then it will have a value of `null`. You only see publicly visible email addresses when authenticated with GitHub. For more information, see [Authentication](https://docs.github.com/rest/overview/resources-in-the-rest-api#authentication). The Emails API enables you to list all of your email addresses, and toggle a primary email to be visible publicly. For more information, see "[Emails API](https://docs.github.com/rest/users/emails)". .EXAMPLE Get-GitHubUserByName -Username 'octocat' Get the 'octocat' user. .NOTES https://docs.github.com/rest/users/users#get-a-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username ) $inputObject = @{ APIEndpoint = "/users/$Username" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [private/Users/Get-GitHubUserByName.ps1] - Done" #endregion - From private/Users/Get-GitHubUserByName.ps1 Write-Verbose "[$scriptName] - [private/Users] - Done" #endregion - From private/Users #region - From private/Utilities Write-Verbose "[$scriptName] - [private/Utilities] - Processing folder" #region - From private/Utilities/Casing Write-Verbose "[$scriptName] - [private/Utilities/Casing] - Processing folder" #region - From private/Utilities/Casing/Convert-StringCasingStyle.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Casing/Convert-StringCasingStyle.ps1] - Importing" filter Convert-StringCasingStyle { <# .SYNOPSIS Convert a string to a different casing style .DESCRIPTION This function converts a string to a different casing style. .EXAMPLE 'thisIsCamelCase' | Convert-StringCasingStyle -To 'snake_case' Convert the string 'thisIsCamelCase' to 'this_is_camel_case' .EXAMPLE 'thisIsCamelCase' | Convert-StringCasingStyle -To 'UPPER_SNAKE_CASE' Convert the string 'thisIsCamelCase' to 'THIS_IS_CAMEL_CASE' .EXAMPLE 'thisIsCamelCase' | Convert-StringCasingStyle -To 'kebab-case' .NOTES General notes #> [OutputType([string])] [CmdletBinding()] param ( # The string to convert [Parameter( Mandatory, ValueFromPipeline )] [string] $Text, # The casing style to convert the string to [Parameter(Mandatory)] [ValidateSet( 'lowercase', 'UPPERCASE', 'Title Case', 'Sentencecase', 'PascalCase', 'camelCase', 'kebab-case', 'UPPER-KEBAB-CASE', 'snake_case', 'UPPER_SNAKE_CASE' )] [string] $To ) $currentStyle = Get-StringCasingStyle -Text $Text $words = Split-StringByCasingStyle -Text $Text -By $currentStyle # Convert the words into the target style switch ($To) { 'lowercase' { ($words -join '').toLower() } 'UPPERCASE' { ($words -join '').toUpper() } 'Title Case' { ($words | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() }) -join ' ' } 'Sentencecase' { $words -join '' | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() } } 'kebab-case' { ($words -join '-').ToLower() } 'snake_case' { ($words -join '_').ToLower() } 'PascalCase' { ($words | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() }) -join '' } 'camelCase' { $words[0].toLower() + (($words | Select-Object -Skip 1 | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1) }) -join '') } 'UPPER_SNAKE_CASE' { ($words -join '_').toUpper() } 'UPPER-KEBAB-CASE' { ($words -join '-').toUpper() } } } Write-Verbose "[$scriptName] - [private/Utilities/Casing/Convert-StringCasingStyle.ps1] - Done" #endregion - From private/Utilities/Casing/Convert-StringCasingStyle.ps1 #region - From private/Utilities/Casing/Get-StringCasingStyle.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Casing/Get-StringCasingStyle.ps1] - Importing" filter Get-StringCasingStyle { <# .SYNOPSIS Detects the casing style of a string .DESCRIPTION This function detects the casing style of a string. .EXAMPLE 'testtesttest' | Get-StringCasingStyle lowercase .EXAMPLE 'TESTTESTTEST' | Get-StringCasingStyle UPPERCASE .EXAMPLE 'Testtesttest' | Get-StringCasingStyle Sentencecase .EXAMPLE 'TestTestTest' | Get-StringCasingStyle PascalCase .EXAMPLE 'testTestTest' | Get-StringCasingStyle camelCase .EXAMPLE 'test-test-test' | Get-StringCasingStyle kebab-case .EXAMPLE 'TEST-TEST-TEST' | Get-StringCasingStyle UPPER-KEBAB-CASE .EXAMPLE 'test_test_test' | Get-StringCasingStyle snake_case .EXAMPLE 'TEST_TEST_TEST' | Get-StringCasingStyle UPPER_SNAKE_CASE .EXAMPLE 'Test_teSt-Test' | Get-StringCasingStyle Unknown #> [OutputType([string])] [CmdletBinding()] param ( # The string to check the casing style of [Parameter( Mandatory, ValueFromPipeline )] [ValidateNotNullOrEmpty()] [string] $Text ) $style = if ([regex]::Match($Text, '^[a-z][a-z0-9]*$').Success) { 'lowercase' } elseif ([regex]::Match($Text, '^[A-Z][A-Z0-9]*$').Success) { 'UPPERCASE' } elseif ([regex]::Match($Text, '^[A-Z][a-z0-9]*$').Success) { 'Sentencecase' } elseif ([regex]::Match($Text, '^([A-Z][a-z]*)(\s+[A-Z][a-z]*)+$').Success) { 'Title Case' } elseif ([regex]::Match($Text, '^[A-Z][a-z0-9]*([A-Z][a-z0-9]*)+$').Success) { 'PascalCase' } elseif ([regex]::Match($Text, '^[a-z][a-z0-9]*([A-Z][a-z0-9]*)+$').Success) { 'camelCase' } elseif ([regex]::Match($Text, '^[a-z][a-z0-9]*(-[a-z0-9]+)+$').Success) { 'kebab-case' } elseif ([regex]::Match($Text, '^[A-Z][A-Z0-9]*(-[A-Z0-9]+)+$').Success) { 'UPPER-KEBAB-CASE' } elseif ([regex]::Match($Text, '^[a-z][a-z0-9]*(_[a-z0-9]+)+$').Success) { 'snake_case' } elseif ([regex]::Match($Text, '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)+$').Success) { 'UPPER_SNAKE_CASE' } else { 'Unknown' } Write-Verbose "Detected casing style: [$style]" $style } Write-Verbose "[$scriptName] - [private/Utilities/Casing/Get-StringCasingStyle.ps1] - Done" #endregion - From private/Utilities/Casing/Get-StringCasingStyle.ps1 #region - From private/Utilities/Casing/Split-StringByCasingStyle.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Casing/Split-StringByCasingStyle.ps1] - Importing" filter Split-StringByCasingStyle { <# .SYNOPSIS Splits a kebab-case string into an array of words .DESCRIPTION This function splits a kebab-case string into an array of words. .EXAMPLE Split-StringByCasingStyle -Text 'this-is-a-kebab-case-string' -By kebab-case this is a kebab case string .EXAMPLE Split-StringByCasingStyle -Text 'this_is_a_kebab_case_string' -By 'snake_case' this is a kebab case string .EXAMPLE Split-StringByCasingStyle -Text 'ThisIsAPascalCaseString' -By 'PascalCase' This Is A Pascal Case String .EXAMPLE Split-StringByCasingStyle -Text 'thisIsACamelCaseString' -By 'camelCase' this Is A Camel Case String .EXAMPLE Split-StringByCasingStyle -Text 'this_is_a-CamelCaseString' -By kebab-case | Split-StringByCasingStyle -By snake_case this_is_a camelcasestring #> [OutputType([string[]])] [CmdletBinding()] param ( # The string to split [Parameter( Mandatory, ValueFromPipeline )] [string] $Text, # The casing style to split the string by [Parameter()] [ValidateSet( 'lowercase', 'UPPERCASE', 'Sentencecase', 'Title Case', 'PascalCase', 'camelCase', 'kebab-case', 'UPPER-KEBAB-CASE', 'snake_case', 'UPPER_SNAKE_CASE' )] [string] $By ) $styles = $PSBoundParameters | Where-Object { $_.Value -eq $true } | Select-Object -ExpandProperty Name Write-Verbose "Splitting string [$Text] by casing style [$($styles -join ', ' )]" $splitText = switch ($By) { 'PascalCase' { [regex]::Matches($Text, '([A-Z][a-z]*)').Value; break } 'camelCase' { [regex]::Matches($Text, '([A-Z][a-z]*)|^[a-z]+').Value; break } 'kebab-case' { $Text -split '-'; break } 'UPPER-KEBAB-CASE' { $Text -split '-'; break } 'snake_case' { $Text -split '_'; break } 'UPPER_SNAKE_CASE' { $Text -split '_'; break } default { $Text -split ' ' } } Write-Verbose "Result: [$($splitText -join ', ')]" $splitText } Write-Verbose "[$scriptName] - [private/Utilities/Casing/Split-StringByCasingStyle.ps1] - Done" #endregion - From private/Utilities/Casing/Split-StringByCasingStyle.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Casing] - Done" #endregion - From private/Utilities/Casing #region - From private/Utilities/Hashtable Write-Verbose "[$scriptName] - [private/Utilities/Hashtable] - Processing folder" #region - From private/Utilities/Hashtable/ConvertFrom-HashTable.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertFrom-HashTable.ps1] - Importing" filter ConvertFrom-HashTable { <# .SYNOPSIS Converts a hashtable to a pscustomobject .DESCRIPTION This function converts a hashtable to a pscustomobject. .EXAMPLE $object = @{a = 1;b = 2;c = 3} $object | ConvertFrom-HashTable | Format-Table a b c - - - 1 2 3 Converts the hashtable to a pscustomobject and displays it in a table. .EXAMPLE $object = @{a = 1;b = 2;c = 3} $object | ConvertFrom-Dictionary | ConvertTo-Json { "a": 1, "b": 2, "c": 3 } Converts the hashtable to a pscustomobject and then to JSON. Using the alias 'ConvertFrom-Dictionary' instead of 'ConvertFrom-HashTable'. #> [OutputType([pscustomobject])] [Alias('ConvertFrom-Dictionary')] [CmdletBinding()] param ( # The hashtable to be converted. The input takes any type of dictionary. The original dictionary is not modified. [Parameter( Mandatory, ValueFromPipeline )] [object]$InputObject ) $InputObject | ConvertTo-Json -Depth 100 | ConvertFrom-Json } Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertFrom-HashTable.ps1] - Done" #endregion - From private/Utilities/Hashtable/ConvertFrom-HashTable.ps1 #region - From private/Utilities/Hashtable/ConvertTo-HashTable.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertTo-HashTable.ps1] - Importing" filter ConvertTo-HashTable { <# .SYNOPSIS Converts an object to a hashtable .DESCRIPTION This function converts an object to a hashtable. .EXAMPLE $object = [pscustomobject]@{a = 1;b = 2;c = 3} $object | ConvertTo-HashTable | Format-Table Name Value ---- ----- a 1 b 2 c 3 Converts the object to a hashtable and displays it in a table. .EXAMPLE $object = [pscustomobject]@{a = 1;b = 2;c = 3} $object | ConvertTo-Dictionary | ConvertTo-Json { "a": 1, "b": 2, "c": 3 } Converts the object to a hashtable and then to JSON. Using the alias 'ConvertTo-Dictionary' instead of 'ConvertTo-HashTable'. #> [OutputType([hashtable])] [Alias('ConvertTo-Dictionary')] [CmdletBinding()] param ( # The object to be converted. The input takes any type of object. The original object is not modified. [Parameter( Mandatory, ValueFromPipeline )] [object]$InputObject, # The casing style of the hashtable keys. [Parameter()] [ValidateSet( 'lowercase', 'UPPERCASE', 'Title Case', 'PascalCase', 'camelCase', 'kebab-case', 'UPPER-KEBAB-CASE', 'snake_case', 'UPPER_SNAKE_CASE' )] [string]$NameCasingStyle ) [hashtable]$hashtable = @{} foreach ($item in $InputObject.PSObject.Properties) { $name = $NameCasingStyle ? ($item.Name | Convert-StringCasingStyle -To $NameCasingStyle) : $item.Name $hashtable[$name] = $item.Value } $hashtable } Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertTo-HashTable.ps1] - Done" #endregion - From private/Utilities/Hashtable/ConvertTo-HashTable.ps1 #region - From private/Utilities/Hashtable/Join-Object.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Join-Object.ps1] - Importing" filter Join-Object { <# .SYNOPSIS Merges two or more objects into a single object .DESCRIPTION Merges two or more objects into a single object. The first object is the main object, and the remaining objects are overrides. The overrides are applied in order, so the last object in the list will override any previous values. .EXAMPLE $main = [pscustomobject]@{a = 1; b = 2; c = 3} $overrides = [pscustomobject]@{a = 4; b = 5; d = 6} $overrides2 = [pscustomobject]@{a = 7; b = 8; e = 9} Join-Object -Main $main -Overrides $overrides, $overrides2 a b c d e - - - - - 7 8 3 6 9 Merges the three objects into a single object. The values from the last object override the values from the previous objects. .EXAMPLE $main = @{a = 1;b = 2} $overrides = @{a = 3;c = 4} Merge-Object -Main $main -Overrides $overrides -AsHashtable Name Value ---- ----- a 3 b 2 c 4 Merges the two hashtables into a single hashtable. The values from the last hashtable override the values from the previous hashtables. Using the alias 'Merge-Object' instead of 'Join-Object'. .EXAMPLE $main = @{a = 1;b = 1;c = 1} $overrides = @{b = 2;d = 2} $overrides2 = @{c = 3;e = 3} $main | Join-Object -Overrides $overrides, $overrides2 | Format-Table a b c d e - - - - - 1 2 3 2 3 Merges the three hashtables into a single hashtable. The values from the last hashtable override the values from the previous hashtables. Using the pipeline to pass the main object instead of the -Main parameter. #> [OutputType([pscustomobject])] [OutputType(ParameterSetName = 'AsHashTable', [hashtable])] [Alias('Merge-Object')] [CmdletBinding(DefaultParameterSetName = '__DefaultSet')] param ( # The main object to merge into. This object will be cloned, so the original object will not be modified. [Parameter( Mandatory, ValueFromPipeline )] [object] $Main, # The objects to merge into the main object [Parameter(Mandatory)] [object[]] $Overrides, # Return the result as a hashtable instead of a pscustomobject [Parameter( Mandatory, ParameterSetName = 'AsHashTable' )] [switch] $AsHashtable ) if ($Main -isnot [hashtable]) { $Main = $Main | ConvertTo-HashTable } $hashtable = $Main.clone() foreach ($Override in $Overrides) { if ($Override -isnot [hashtable]) { $Override = $Override | ConvertTo-HashTable } $Override.Keys | ForEach-Object { $hashtable[$_] = $Override[$_] } } if ($AsHashtable) { return $hashtable } $hashtable | ConvertFrom-HashTable } Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Join-Object.ps1] - Done" #endregion - From private/Utilities/Hashtable/Join-Object.ps1 #region - From private/Utilities/Hashtable/Remove-HashTableEntries.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Remove-HashTableEntries.ps1] - Importing" filter Remove-HashtableEntries { [OutputType([void])] [CmdletBinding()] param ( [Parameter( Mandatory, ValueFromPipeline )] [hashtable] $Hashtable, [Parameter()] [switch] $NullOrEmptyValues, [Parameter()] [string[]] $RemoveTypes, [Parameter()] [string[]] $RemoveNames, [Parameter()] [string[]] $KeepTypes, [Parameter()] [string[]] $KeepNames ) if ($NullOrEmptyValues) { Write-Verbose 'Remove keys with null or empty values' ($Hashtable.GetEnumerator() | Where-Object { -not $_.Value }) | ForEach-Object { Write-Verbose " - [$($_.Name)] - Value: [$($_.Value)] - Remove" $Hashtable.Remove($_.Name) } } if ($RemoveTypes) { Write-Verbose "Remove keys of type: [$RemoveTypes]" ($Hashtable.GetEnumerator() | Where-Object { ($_.Value.GetType().Name -in $RemoveTypes) }) | ForEach-Object { Write-Verbose " - [$($_.Name)] - Type: [$($_.Value.GetType().Name)] - Remove" $Hashtable.Remove($_.Name) } } if ($KeepTypes) { Write-Verbose "Remove keys NOT of type: [$KeepTypes]" ($Hashtable.GetEnumerator() | Where-Object { ($_.Value.GetType().Name -notin $KeepTypes) }) | ForEach-Object { Write-Verbose " - [$($_.Name)] - Type: [$($_.Value.GetType().Name)] - Remove" $Hashtable.Remove($_.Name) } } if ($RemoveNames) { Write-Verbose "Remove keys named: [$RemoveNames]" ($Hashtable.GetEnumerator() | Where-Object { $_.Name -in $RemoveNames }) | ForEach-Object { Write-Verbose " - [$($_.Name)] - Remove" $Hashtable.Remove($_.Name) } } if ($KeepNames) { Write-Verbose "Remove keys NOT named: [$KeepNames]" ($Hashtable.GetEnumerator() | Where-Object { $_.Name -notin $KeepNames }) | ForEach-Object { Write-Verbose " - [$($_.Name)] - Remove" $Hashtable.Remove($_.Name) } } } Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Remove-HashTableEntries.ps1] - Done" #endregion - From private/Utilities/Hashtable/Remove-HashTableEntries.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Hashtable] - Done" #endregion - From private/Utilities/Hashtable #region - From private/Utilities/Web Write-Verbose "[$scriptName] - [private/Utilities/Web] - Processing folder" #region - From private/Utilities/Web/ConvertTo-QueryString.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Web/ConvertTo-QueryString.ps1] - Importing" filter ConvertTo-QueryString { <# .SYNOPSIS Convert an object to a query string .DESCRIPTION Convert an object to a query string .EXAMPLE ConvertTo-QueryString -InputObject @{a=1;b=2} ?a=1&b=2 .EXAMPLE ConvertTo-QueryString -InputObject @{a='this is value of a';b='valueOfB'} ?a=this%20is%20value%20of%20a&b=valueOfB .EXAMPLE ConvertTo-QueryString -InputObject @{a='this is value of a';b='valueOfB'} -AsURLEncoded ?a=this+is+value+of+a&b=valueOfB #> [OutputType([string])] [CmdletBinding()] param( [Parameter( Mandatory, ValueFromPipeline )] [object] $InputObject, [Parameter()] [switch] $AsURLEncoded ) if ($InputObject -isnot [hashtable]) { $InputObject = $InputObject | ConvertTo-HashTable } $parameters = if ($AsURLEncoded) { ($InputObject.GetEnumerator() | ForEach-Object { "$([System.Web.HttpUtility]::UrlEncode($_.Key))=$([System.Web.HttpUtility]::UrlEncode($_.Value))" }) -join '&' } else { ($InputObject.GetEnumerator() | ForEach-Object { "$([System.Uri]::EscapeDataString($_.Key))=$([System.Uri]::EscapeDataString($_.Value))" }) -join '&' } if ($parameters) { '?' + $parameters } } Write-Verbose "[$scriptName] - [private/Utilities/Web/ConvertTo-QueryString.ps1] - Done" #endregion - From private/Utilities/Web/ConvertTo-QueryString.ps1 Write-Verbose "[$scriptName] - [private/Utilities/Web] - Done" #endregion - From private/Utilities/Web Write-Verbose "[$scriptName] - [private/Utilities] - Done" #endregion - From private/Utilities Write-Verbose "[$scriptName] - [private] - Done" #endregion - From private #region - From public Write-Verbose "[$scriptName] - [public] - Processing folder" #region - From public/Actions Write-Verbose "[$scriptName] - [public/Actions] - Processing folder" #region - From public/Actions/Disable-GitHubWorkflow.ps1 Write-Verbose "[$scriptName] - [public/Actions/Disable-GitHubWorkflow.ps1] - Importing" filter Disable-GitHubWorkflow { <# .NOTES https://docs.github.com/rest/reference/actions#disable-a-workflow #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string[]] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/disable" Method = 'PUT' } Invoke-GitHubAPI @inputObject | Out-Null } Write-Verbose "[$scriptName] - [public/Actions/Disable-GitHubWorkflow.ps1] - Done" #endregion - From public/Actions/Disable-GitHubWorkflow.ps1 #region - From public/Actions/Enable-GitHubWorkflow.ps1 Write-Verbose "[$scriptName] - [public/Actions/Enable-GitHubWorkflow.ps1] - Importing" filter Enable-GitHubWorkflow { <# .NOTES https://docs.github.com/rest/reference/actions#enable-a-workflow #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string[]] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/enable" Method = 'PUT' } Invoke-GitHubAPI @inputObject | Out-Null } Write-Verbose "[$scriptName] - [public/Actions/Enable-GitHubWorkflow.ps1] - Done" #endregion - From public/Actions/Enable-GitHubWorkflow.ps1 #region - From public/Actions/Get-GitHubWorkflow.ps1 Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflow.ps1] - Importing" filter Get-GitHubWorkflow { <# .SYNOPSIS Lists the workflows in a repository. .DESCRIPTION Anyone with read access to the repository can use this endpoint. If the repository is private you must use an access token with the repo scope. GitHub Apps must have the actions:read permission to use this endpoint. .EXAMPLE Get-GitHubWorkflow -Owner 'octocat' -Repo 'hello-world' Gets all workflows in the 'octocat/hello-world' repository. .EXAMPLE Get-GitHubWorkflow -Owner 'octocat' -Repo 'hello-world' -Name 'hello-world.yml' Gets the 'hello-world.yml' workflow in the 'octocat/hello-world' repository. .NOTES https://docs.github.com/rest/actions/workflows?apiVersion=2022-11-28#list-repository-workflows #> [CmdletBinding(DefaultParameterSetName = 'ByName')] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter(ParameterSetName = 'ByName')] [string] $Name, [Parameter(ParameterSetName = 'ByID')] [string] $ID, [Parameter()] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response.workflows } Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflow.ps1] - Done" #endregion - From public/Actions/Get-GitHubWorkflow.ps1 #region - From public/Actions/Get-GitHubWorkflowRun.ps1 Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowRun.ps1] - Importing" filter Get-GitHubWorkflowRun { <# .NOTES https://docs.github.com/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-workflow https://docs.github.com/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository #> [CmdletBinding(DefaultParameterSetName = 'Repo')] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter(ParameterSetName = 'ByName')] [string] $Name, [Parameter(ParameterSetName = 'ByID')] [string] $ID, [Parameter()] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } if ($Name) { $ID = (Get-GitHubWorkflow -Owner $Owner -Repo $Repo -Name $Name).id } if ($ID) { $Uri = "/repos/$Owner/$Repo/actions/workflows/$ID/runs" } else { $Uri = "/repos/$Owner/$Repo/actions/runs" } $inputObject = @{ APIEndpoint = $Uri Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response.workflow_runs } Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowRun.ps1] - Done" #endregion - From public/Actions/Get-GitHubWorkflowRun.ps1 #region - From public/Actions/Get-GitHubWorkflowUsage.ps1 Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowUsage.ps1] - Importing" filter Get-GitHubWorkflowUsage { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER Owner Parameter description .PARAMETER Repo Parameter description .PARAMETER ID Parameter description .EXAMPLE An example .NOTES https://docs.github.com/rest/reference/actions#get-workflow-usage #> [CmdletBinding( DefaultParameterSetName = 'ByName' )] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string[]] $ID ) $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/timing" } (Invoke-GitHubAPI @inputObject).Response.billable } Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowUsage.ps1] - Done" #endregion - From public/Actions/Get-GitHubWorkflowUsage.ps1 #region - From public/Actions/Remove-GitHubWorkflowRun.ps1 Write-Verbose "[$scriptName] - [public/Actions/Remove-GitHubWorkflowRun.ps1] - Importing" filter Remove-GitHubWorkflowRun { [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID ) $inputObject = @{ APIEndpoint = "repos/$Owner/$Repo/actions/runs/$ID" Method = 'DELETE' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Actions/Remove-GitHubWorkflowRun.ps1] - Done" #endregion - From public/Actions/Remove-GitHubWorkflowRun.ps1 #region - From public/Actions/Start-GitHubWorkflow.ps1 Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflow.ps1] - Importing" filter Start-GitHubWorkflow { <# .SYNOPSIS Start a workflow run using the workflow's ID. .DESCRIPTION Start a workflow run using the workflow's ID. .EXAMPLE Get-GitHubWorkflow | Where-Object name -NotLike '.*' | Start-GitHubWorkflow -Inputs @{ staticValidation = $true deploymentValidation = $false removeDeployment = $true prerelease = $false } .NOTES # API Reference # https://docs.github.com/free-pro-team@latest/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Alias('workflow_id')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID, [Parameter( ValueFromPipelineByPropertyName )] [Alias('branch', 'tag')] [string] $Ref = 'main', [Parameter()] [hashtable] $Inputs = @{} ) $body = @{ ref = $Ref inputs = $Inputs } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/dispatches" Method = 'POST' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflow.ps1] - Done" #endregion - From public/Actions/Start-GitHubWorkflow.ps1 #region - From public/Actions/Start-GitHubWorkflowReRun.ps1 Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflowReRun.ps1] - Importing" filter Start-GitHubWorkflowReRun { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER Owner Parameter description .PARAMETER Repo Parameter description .PARAMETER ID Parameter description .EXAMPLE An example .NOTES https://docs.github.com/rest/reference/actions#re-run-a-workflow #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Alias('workflow_id')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID ) $inputObject = @{ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repo/actions/runs/$ID/rerun" } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflowReRun.ps1] - Done" #endregion - From public/Actions/Start-GitHubWorkflowReRun.ps1 #region - From public/Actions/Stop-GitHubWorkflowRun.ps1 Write-Verbose "[$scriptName] - [public/Actions/Stop-GitHubWorkflowRun.ps1] - Importing" filter Stop-GitHubWorkflowRun { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER Owner Parameter description .PARAMETER Repo Parameter description .PARAMETER ID Parameter description .EXAMPLE An example .NOTES https://docs.github.com/rest/reference/actions#cancel-a-workflow-run #> [CmdletBinding()] [alias('Cancel-GitHubWorkflowRun')] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Alias('workflow_id')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID ) $inputObject = @{ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repo/actions/runs/$ID/cancel" } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Actions/Stop-GitHubWorkflowRun.ps1] - Done" #endregion - From public/Actions/Stop-GitHubWorkflowRun.ps1 Write-Verbose "[$scriptName] - [public/Actions] - Done" #endregion - From public/Actions #region - From public/API Write-Verbose "[$scriptName] - [public/API] - Processing folder" #region - From public/API/Invoke-GitHubAPI.ps1 Write-Verbose "[$scriptName] - [public/API/Invoke-GitHubAPI.ps1] - Importing" filter Invoke-GitHubAPI { <# .SYNOPSIS Calls the GitHub API using the provided parameters. .DESCRIPTION This function is a wrapper around Invoke-RestMethod tailored for calling GitHub's API. It automatically handles the endpoint URI construction, headers, and token authentication. .EXAMPLE Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET Gets all open pull requests for the specified repository. .EXAMPLE Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' } Gets all open pull requests for the specified repository, filtered by the 'state' parameter. .EXAMPLE Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' } -Accept 'application/vnd.github.v3+json' Gets all open pull requests for the specified repository, filtered by the 'state' parameter, and using the specified 'Accept' header. #> [CmdletBinding()] param ( # The HTTP method to be used for the API request. It can be one of the following: GET, POST, PUT, DELETE, or PATCH. [Parameter()] [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'GET', # The base URI for the GitHub API. This is usually 'https://api.github.com', but can be adjusted if necessary. [Parameter()] [string] $ApiBaseUri = (Get-GitHubConfig -Name ApiBaseUri), # The specific endpoint for the API call, e.g., '/repos/user/repo/pulls'. [Parameter(Mandatory)] [string] $ApiEndpoint, # The body of the API request. This can be a hashtable or a string. If a hashtable is provided, it will be converted to JSON. [Parameter()] [Object] $Body, # The 'Accept' header for the API request. If not provided, the default will be used by GitHub's API. [Parameter()] [string] $Accept = 'application/vnd.github+json; charset=utf-8', # Specifies the HTTP version used for the request. [Parameter()] [version] $HttpVersion = '2.0', # Support Pagination Relation Links per RFC5988. [Parameter()] [bool] $FollowRelLink = $true, # The secure token used for authentication in the GitHub API. It should be stored as a SecureString to ensure it's kept safe in memory. [Parameter()] [SecureString] $AccessToken = (Get-GitHubConfig -Name AccessToken), # The 'Content-Type' header for the API request. The default is 'application/vnd.github+json'. [Parameter()] [string] $ContentType = 'application/vnd.github+json; charset=utf-8', # The GitHub API version to be used. By default, it pulls from a configuration script variable. [Parameter()] [string] $Version = (Get-GitHubConfig -Name ApiVersion) ) if (Test-GitHubAccessTokenRefreshRequired) { Connect-GitHubAccount -Silent $AccessToken = (Get-GitHubConfig -Name AccessToken) } $functionName = $MyInvocation.MyCommand.Name $headers = @{ Accept = $Accept 'X-GitHub-Api-Version' = $Version } Remove-HashTableEntries -Hashtable $headers -NullOrEmptyValues $URI = ("$ApiBaseUri/" -replace '/$', '') + ("/$ApiEndpoint" -replace '^/', '') # $AccessTokenAsPlainText = ConvertFrom-SecureString $AccessToken -AsPlainText # # Swap out this by using the -Authentication Bearer -Token $AccessToken # switch -Regex ($AccessTokenAsPlainText) { # '^ghp_|^github_pat_' { # $headers.authorization = "token $AccessTokenAsPlainText" # } # '^ghu_|^gho_' { # $headers.authorization = "Bearer $AccessTokenAsPlainText" # } # default { # $tokenPrefix = $AccessTokenAsPlainText -replace '_.*$', '_*' # $errorMessage = "Unexpected AccessToken format: $tokenPrefix" # Write-Error $errorMessage # throw $errorMessage # } # } $APICall = @{ Uri = $URI Method = $Method Headers = $Headers Authentication = 'Bearer' Token = $AccessToken ContentType = $ContentType HttpVersion = $HttpVersion FollowRelLink = $FollowRelLink StatusCodeVariable = 'APICallStatusCode' ResponseHeadersVariable = 'APICallResponseHeaders' } $APICall | Remove-HashTableEntries -NullOrEmptyValues if ($Body) { # Use body to create the query string for GET requests if ($Method -eq 'GET') { $queryString = $Body | ConvertTo-QueryString $APICall.Uri = $APICall.Uri + $queryString } # Use body to create the form data if ($Body -is [string]) { $APICall.Body = $Body } else { $APICall.Body = $Body | ConvertTo-Json -Depth 100 } } Invoke-RestMethod @APICall | ForEach-Object { $statusCode = $APICallStatusCode | ConvertTo-Json -Depth 100 | ConvertFrom-Json $responseHeaders = $APICallResponseHeaders | ConvertTo-Json -Depth 100 | ConvertFrom-Json [pscustomobject]@{ Request = $APICall Response = $_ StatusCode = $statusCode ResponseHeaders = $responseHeaders } } } Write-Verbose "[$scriptName] - [public/API/Invoke-GitHubAPI.ps1] - Done" #endregion - From public/API/Invoke-GitHubAPI.ps1 Write-Verbose "[$scriptName] - [public/API] - Done" #endregion - From public/API #region - From public/Auth Write-Verbose "[$scriptName] - [public/Auth] - Processing folder" #region - From public/Auth/Connect-GitHubAccount.ps1 Write-Verbose "[$scriptName] - [public/Auth/Connect-GitHubAccount.ps1] - Importing" function Connect-GitHubAccount { <# .SYNOPSIS Connects to GitHub using a personal access token or device code login. .DESCRIPTION Connects to GitHub using a personal access token or device code login. For device flow / device code login: PowerShell requests device and user verification codes and gets the authorization URL where you will enter the user verification code. In GitHub you will be asked to enter a user verification code at https://github.com/login/device. PowerShell will keep polling GitHub for the user authentication status. Once you have authorized the device, the app will be able to make API calls with a new access token. .EXAMPLE Connect-GitHubAccount Connects to GitHub using a device flow login. If the user has already logged in, the access token will be refreshed. .EXAMPLE Connect-GitHubAccount -AccessToken ! Enter your personal access token: ************* User gets prompted for the access token and stores it in the secret store. The token is used when connecting to GitHub. .EXAMPLE Connect-GitHubAccount -Mode 'OAuthApp' -Scope 'gist read:org repo workflow' Connects to GitHub using a device flow login and sets the scope of the access token. .NOTES https://docs.github.com/rest/overview/other-authentication-methods#authenticating-for-saml-sso #> [Alias('Connect-GHAccount')] [Alias('Connect-GitHub')] [Alias('Connect-GH')] [Alias('Login-GitHubAccount')] [Alias('Login-GHAccount')] [Alias('Login-GitHub')] [Alias('Login-GH')] [OutputType([void])] [CmdletBinding(DefaultParameterSetName = 'DeviceFlow')] param ( # Choose between authentication methods, either OAuthApp or GitHubApp. # For more info about the types of authentication visit: # https://docs.github.com/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps [Parameter(ParameterSetName = 'DeviceFlow')] [ValidateSet('OAuthApp', 'GitHubApp')] [string] $Mode = 'GitHubApp', # The scope of the access token, when using OAuth authentication. # Provide the list of scopes as space-separated values. # For more information on scopes visit: # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps [Parameter(ParameterSetName = 'DeviceFlow')] [string] $Scope = 'gist read:org repo workflow', # The personal access token to use for authentication. [Parameter( Mandatory, ParameterSetName = 'PAT' )] [Alias('Token')] [Alias('PAT')] [switch] $AccessToken, # Set the default owner to use in commands. [Parameter()] [Alias('Organization')] [Alias('Org')] [string] $Owner, # Set the default repository to use in commands. [Parameter()] [Alias('Repository')] [string] $Repo, # Suppresses the output of the function. [Parameter()] [Alias('Quiet')] [Alias('q')] [Alias('s')] [switch] $Silent ) $envVars = Get-ChildItem -Path 'Env:' $systemToken = $envVars | Where-Object Name -In 'GH_TOKEN', 'GITHUB_TOKEN' | Select-Object -First 1 $systemTokenPresent = $systemToken.count -gt 0 $AuthType = $systemTokenPresent ? 'sPAT' : $PSCmdlet.ParameterSetName switch ($AuthType) { 'DeviceFlow' { Write-Verbose 'Logging in using device flow...' $clientID = $script:Auth.$Mode.ClientID if ($Mode -ne (Get-GitHubConfig -Name DeviceFlowType -ErrorAction SilentlyContinue)) { Write-Verbose "Using $Mode authentication..." $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope } else { $accessTokenValidity = [datetime](Get-GitHubConfig -Name 'AccessTokenExpirationDate') - (Get-Date) $accessTokenIsValid = $accessTokenValidity.Seconds -gt 0 $hours = $accessTokenValidity.Hours.ToString().PadLeft(2, '0') $minutes = $accessTokenValidity.Minutes.ToString().PadLeft(2, '0') $seconds = $accessTokenValidity.Seconds.ToString().PadLeft(2, '0') $accessTokenValidityText = "$hours`:$minutes`:$seconds" if ($accessTokenIsValid) { if ($accessTokenValidity.TotalHours -gt $script:Auth.AccessTokenGracePeriodInHours) { if (-not $Silent) { Write-Host '✓ ' -ForegroundColor Green -NoNewline Write-Host "Access token is still valid for $accessTokenValidityText ..." } break } else { if (-not $Silent) { Write-Host '⚠' -ForegroundColor Yellow -NoNewline Write-Host "Access token remaining validity $accessTokenValidityText. Refreshing access token..." } $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name RefreshToken) } } else { $refreshTokenValidity = [datetime](Get-GitHubConfig -Name 'RefreshTokenExpirationDate') - (Get-Date) $refreshTokenIsValid = $refreshTokenValidity.Seconds -gt 0 if ($refreshTokenIsValid) { if (-not $Silent) { Write-Host '⚠' -ForegroundColor Yellow -NoNewline Write-Host 'Access token expired. Refreshing access token...' } $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name RefreshToken) } else { Write-Verbose "Using $Mode authentication..." $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope } } } Reset-GitHubConfig -Scope 'Auth' switch ($Mode) { 'GitHubApp' { $settings = @{ AccessToken = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token AccessTokenExpirationDate = (Get-Date).AddSeconds($tokenResponse.expires_in) AccessTokenType = $tokenResponse.access_token -replace '_.*$', '_*' ApiBaseUri = 'https://api.github.com' ApiVersion = '2022-11-28' AuthType = $AuthType DeviceFlowType = $Mode RefreshToken = ConvertTo-SecureString -AsPlainText $tokenResponse.refresh_token RefreshTokenExpirationDate = (Get-Date).AddSeconds($tokenResponse.refresh_token_expires_in) Scope = $tokenResponse.scope } } 'OAuthApp' { $settings = @{ AccessToken = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token AccessTokenType = $tokenResponse.access_token -replace '_.*$', '_*' ApiBaseUri = 'https://api.github.com' ApiVersion = '2022-11-28' AuthType = $AuthType DeviceFlowType = $Mode Scope = $tokenResponse.scope } } } Set-GitHubConfig @settings break } 'PAT' { Write-Verbose 'Logging in using personal access token...' Reset-GitHubConfig -Scope 'Auth' Write-Host '! ' -ForegroundColor DarkYellow -NoNewline Start-Process 'https://github.com/settings/tokens' $accessTokenValue = Read-Host -Prompt 'Enter your personal access token' -AsSecureString $accessTokenType = (ConvertFrom-SecureString $accessTokenValue -AsPlainText) -replace '_.*$', '_*' if ($accessTokenType -notmatch '^ghp_|^github_pat_') { Write-Warning '⚠' -ForegroundColor Yellow -NoNewline Write-Warning "Unexpected access token format: $accessTokenType" } $settings = @{ AccessToken = $accessTokenValue AccessTokenType = $accessTokenType ApiBaseUri = 'https://api.github.com' ApiVersion = '2022-11-28' AuthType = $AuthType } Set-GitHubConfig @settings break } 'sPAT' { Write-Verbose 'Logging in using system access token...' Reset-GitHubConfig -Scope 'Auth' $prefix = $systemToken.Value -replace '_.*$', '_*' $settings = @{ AccessToken = ConvertTo-SecureString -AsPlainText $systemToken.Value AccessTokenType = $prefix ApiBaseUri = 'https://api.github.com' ApiVersion = '2022-11-28' AuthType = 'sPAT' } Set-GitHubConfig @settings } } if ($AuthType -ne 'sPAT') { $user = Get-GitHubUser $username = $user.login Set-GitHubConfig -UserName $username } else { $username = 'system' } if (-not $Silent) { Write-Host '✓ ' -ForegroundColor Green -NoNewline Write-Host "Logged in as $username!" } $systemRepo = $envVars | Where-Object Name -EQ 'GITHUB_REPOSITORY' $systemRepoPresent = $systemRepo.count -gt 0 if ($Owner) { Set-GitHubConfig -Owner $Owner } elseif ($systemRepoPresent) { $owner = $systemRepo.Value.Split('/')[0] Set-GitHubConfig -Owner $owner } if ($Repo) { Set-GitHubConfig -Repo $Repo } elseif ($systemRepoPresent) { $repo = $systemRepo.Value.Split('/')[-1] Set-GitHubConfig -Repo $repo } } Write-Verbose "[$scriptName] - [public/Auth/Connect-GitHubAccount.ps1] - Done" #endregion - From public/Auth/Connect-GitHubAccount.ps1 #region - From public/Auth/Disconnect-GitHubAccount.ps1 Write-Verbose "[$scriptName] - [public/Auth/Disconnect-GitHubAccount.ps1] - Importing" function Disconnect-GitHubAccount { <# .SYNOPSIS Disconnects from GitHub and removes the current GitHub configuration. .DESCRIPTION Disconnects from GitHub and removes the current GitHub configuration. .EXAMPLE Disconnect-GitHubAccount Disconnects from GitHub and removes the current GitHub configuration. #> [Alias('Disconnect-GHAccount')] [Alias('Disconnect-GitHub')] [Alias('Disconnect-GH')] [Alias('Logout-GitHubAccount')] [Alias('Logout-GHAccount')] [Alias('Logout-GitHub')] [Alias('Logout-GH')] [Alias('Logoff-GitHubAccount')] [Alias('Logoff-GHAccount')] [Alias('Logoff-GitHub')] [Alias('Logoff-GH')] [OutputType([void])] [CmdletBinding()] param () Reset-GitHubConfig -Scope 'All' Write-Host '✓ ' -ForegroundColor Green -NoNewline Write-Host 'Logged out of GitHub!' } Write-Verbose "[$scriptName] - [public/Auth/Disconnect-GitHubAccount.ps1] - Done" #endregion - From public/Auth/Disconnect-GitHubAccount.ps1 Write-Verbose "[$scriptName] - [public/Auth] - Done" #endregion - From public/Auth #region - From public/Branches Write-Verbose "[$scriptName] - [public/Branches] - Processing folder" #region - From public/Branches/Get-GitHubRepoBranch.ps1 Write-Verbose "[$scriptName] - [public/Branches/Get-GitHubRepoBranch.ps1] - Importing" filter Get-GitHubRepoBranch { [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/branches" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Branches/Get-GitHubRepoBranch.ps1] - Done" #endregion - From public/Branches/Get-GitHubRepoBranch.ps1 Write-Verbose "[$scriptName] - [public/Branches] - Done" #endregion - From public/Branches #region - From public/Config Write-Verbose "[$scriptName] - [public/Config] - Processing folder" #region - From public/Config/Get-GitHubConfig.ps1 Write-Verbose "[$scriptName] - [public/Config/Get-GitHubConfig.ps1] - Importing" function Get-GitHubConfig { <# .SYNOPSIS Get configuration value. .DESCRIPTION Get a named configuration value from the GitHub configuration file. .EXAMPLE Get-GitHubConfig -Name ApiBaseUri Get the current GitHub configuration for the ApiBaseUri. #> [Alias('Get-GHConfig')] [Alias('GGHC')] [OutputType([object])] [CmdletBinding()] param ( # Choose a configuration name to get. [Parameter()] [ValidateSet( 'AccessToken', 'AccessTokenExpirationDate', 'AccessTokenType', 'ApiBaseUri', 'ApiVersion', 'AuthType', 'DeviceFlowType', 'Owner', 'RefreshToken', 'RefreshTokenExpirationDate', 'Repo', 'Scope', 'UserName' )] [string] $Name ) $prefix = $script:SecretVault.Prefix $RefreshTokenData = (Get-SecretInfo -Name "$prefix`RefreshToken").Metadata | ConvertFrom-HashTable | ConvertTo-HashTable $AccessTokenData = (Get-SecretInfo -Name "$prefix`AccessToken").Metadata | ConvertFrom-HashTable | ConvertTo-HashTable $metadata = Join-Object -Main $RefreshTokenData -Overrides $AccessTokenData -AsHashtable switch($Name) { 'AccessToken' { Get-Secret -Name "$prefix`AccessToken" } 'RefreshToken' { Get-Secret -Name "$prefix`RefreshToken" } default { if ($Name) { $metadata.$Name } else { $metadata.GetEnumerator() | Sort-Object -Property Name } } } } Write-Verbose "[$scriptName] - [public/Config/Get-GitHubConfig.ps1] - Done" #endregion - From public/Config/Get-GitHubConfig.ps1 #region - From public/Config/Set-GitHubConfig.ps1 Write-Verbose "[$scriptName] - [public/Config/Set-GitHubConfig.ps1] - Importing" function Set-GitHubConfig { <# .SYNOPSIS Set the GitHub configuration. .DESCRIPTION Set the GitHub configuration. Specific scopes can be set by using the parameters. .EXAMPLE Set-GitHubConfig -APIBaseURI 'https://api.github.com" -APIVersion '2022-11-28' Sets the App.API scope of the GitHub configuration. .EXAMPLE Set-GitHubConfig -Name "MyFavouriteRepo" -Value 'https://github.com/PSModule/GitHub' Sets a item called 'MyFavouriteRepo' in the GitHub configuration. #> [Alias('Set-GHConfig')] [CmdletBinding()] param ( # Set the access token type. [Parameter()] [string] $AccessTokenType, # Set the access token. [Parameter()] [securestring] $AccessToken, # Set the access token expiration date. [Parameter()] [datetime] $AccessTokenExpirationDate, # Set the API Base URI. [Parameter()] [string] $ApiBaseUri, # Set the GitHub API Version. [Parameter()] [string] $ApiVersion, # Set the authentication type. [Parameter()] [string] $AuthType, # Set the device flow type. [Parameter()] [string] $DeviceFlowType, # Set the default for the Owner parameter. [Parameter()] [string] $Owner, # Set the refresh token. [Parameter()] [securestring] $RefreshToken, # Set the refresh token expiration date. [Parameter()] [datetime] $RefreshTokenExpirationDate, # Set the default for the Repo parameter. [Parameter()] [string] $Repo, # Set the scope. [Parameter()] [string] $Scope, # Set the GitHub username. [Parameter()] [string] $UserName ) $prefix = $script:SecretVault.Prefix #region AccessToken $secretName = "$prefix`AccessToken" $removeKeys = 'AccessToken', 'RefreshToken', 'RefreshTokenExpirationDate' $keepTypes = 'String', 'Int', 'DateTime' # Get existing metadata if it exists $newSecretMetadata = @{} if (Get-SecretInfo -Name $secretName) { $secretGetInfoParam = @{ Name = $secretName Vault = $script:SecretVault.Name } $secretInfo = Get-SecretInfo @secretGetInfoParam Write-Verbose "$secretName - secretInfo : $($secretInfo | Out-String)" $secretMetadata = $secretInfo.Metadata | ConvertFrom-HashTable | ConvertTo-HashTable $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $secretMetadata -AsHashtable } # Get metadata updates from parameters and clean up unwanted data $updateSecretMetadata = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)" Write-Verbose "updateSecretMetadataType : $($updateSecretMetadata.GetType())" Remove-HashTableEntries -Hashtable $updateSecretMetadata -KeepTypes $keepTypes -RemoveNames $removeKeys Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)" $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $updateSecretMetadata -AsHashtable Write-Verbose "newSecretMetadata : $($newSecretMetadata | Out-String)" Write-Verbose "newSecretMetadataType : $($newSecretMetadata.GetType())" if ($AccessToken) { $accessTokenSetParam = @{ Name = $secretName Vault = $script:SecretVault.Name SecureStringSecret = $AccessToken } Set-Secret @accessTokenSetParam } if (Get-SecretInfo -Name $secretName) { $secretSetInfoParam = @{ Name = $secretName Vault = $script:SecretVault.Name Metadata = $newSecretMetadata } Set-SecretInfo @secretSetInfoParam } #endregion AccessToken #region RefreshToken $secretName = "$prefix`RefreshToken" $removeKeys = 'AccessToken', 'RefreshToken', 'AccessTokenExpirationDate' # Get existing metadata if it exists $newSecretMetadata = @{} if (Get-SecretInfo -Name $secretName) { $secretGetInfoParam = @{ Name = $secretName Vault = $script:SecretVault.Name } $secretInfo = Get-SecretInfo @secretGetInfoParam Write-Verbose "$secretName - secretInfo : $($secretInfo | Out-String)" $secretMetadata = $secretInfo.Metadata | ConvertFrom-HashTable | ConvertTo-HashTable $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $secretMetadata -AsHashtable } # Get metadata updates from parameters and clean up unwanted data $updateSecretMetadata = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)" Write-Verbose "updateSecretMetadataType : $($updateSecretMetadata.GetType())" Remove-HashTableEntries -Hashtable $updateSecretMetadata -KeepTypes $keepTypes -RemoveNames $removeKeys Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)" $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $updateSecretMetadata -AsHashtable Write-Verbose "newSecretMetadata : $($newSecretMetadata | Out-String)" Write-Verbose "newSecretMetadataType : $($newSecretMetadata.GetType())" if ($RefreshToken) { $refreshTokenSetParam = @{ Name = $secretName Vault = $script:SecretVault.Name SecureStringSecret = $RefreshToken } Set-Secret @refreshTokenSetParam } if (Get-SecretInfo -Name $secretName) { $secretSetInfoParam = @{ Name = $secretName Vault = $script:SecretVault.Name Metadata = $newSecretMetadata } Set-SecretInfo @secretSetInfoParam } #endregion AccessToken } Write-Verbose "[$scriptName] - [public/Config/Set-GitHubConfig.ps1] - Done" #endregion - From public/Config/Set-GitHubConfig.ps1 Write-Verbose "[$scriptName] - [public/Config] - Done" #endregion - From public/Config #region - From public/Deployments Write-Verbose "[$scriptName] - [public/Deployments] - Processing folder" #region - From public/Deployments/Get-GitHubEnvironment.ps1 Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironment.ps1] - Importing" filter Get-GitHubEnvironment { <# .SYNOPSIS Get GitHub environment .DESCRIPTION Long description .PARAMETER Owner Parameter description .PARAMETER Repo Parameter description .EXAMPLE An example .NOTES https://docs.github.com/rest/reference/repos#get-all-environments #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/environments" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironment.ps1] - Done" #endregion - From public/Deployments/Get-GitHubEnvironment.ps1 #region - From public/Deployments/Get-GitHubEnvironmentSecrets.ps1 Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironmentSecrets.ps1] - Importing" filter Get-GitHubEnvironmentSecrets { <# .SYNOPSIS Get GitHub environment secrets .DESCRIPTION Long description .PARAMETER Owner Parameter description .PARAMETER Repo Parameter description .PARAMETER EnvironmentName Parameter description .EXAMPLE An example .NOTES https://docs.github.com/rest/reference/repos#get-all-environments #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [Alias('name')] [string] $EnvironmentName ) $RepoID = (Get-GitHubRepo).id $inputObject = @{ APIEndpoint = "/repositories/$RepoID/environments/$EnvironmentName/secrets" Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironmentSecrets.ps1] - Done" #endregion - From public/Deployments/Get-GitHubEnvironmentSecrets.ps1 #region - From public/Deployments/Update-GitHubEnvironment.ps1 Write-Verbose "[$scriptName] - [public/Deployments/Update-GitHubEnvironment.ps1] - Importing" filter Update-GitHubEnvironment { <# .NOTES https://docs.github.com/rest/reference/repos#create-or-update-an-environment #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo), [Alias('environment_name')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Name ) $body = @{ owner = $Owner repo = $Repo environment_name = $Name } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/environments/$Name" Method = 'PUT' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Deployments/Update-GitHubEnvironment.ps1] - Done" #endregion - From public/Deployments/Update-GitHubEnvironment.ps1 Write-Verbose "[$scriptName] - [public/Deployments] - Done" #endregion - From public/Deployments #region - From public/Emojis Write-Verbose "[$scriptName] - [public/Emojis] - Processing folder" #region - From public/Emojis/Get-GitHubEmojis.ps1 Write-Verbose "[$scriptName] - [public/Emojis/Get-GitHubEmojis.ps1] - Importing" filter Get-GitHubEmojis { <# .NOTES https://docs.github.com/rest/reference/emojis#get-emojis #> [CmdletBinding()] param ( [Parameter()] [string] $Destination ) $inputObject = @{ APIEndpoint = '/emojis' Method = 'GET' } $response = (Invoke-GitHubAPI @inputObject).Response if (Test-Path -Path $Destination) { $response.PSObject.Properties | ForEach-Object -Parallel { Invoke-WebRequest -Uri $_.Value -OutFile "$using:Destination/$($_.Name).png" } } else { $response } } Write-Verbose "[$scriptName] - [public/Emojis/Get-GitHubEmojis.ps1] - Done" #endregion - From public/Emojis/Get-GitHubEmojis.ps1 Write-Verbose "[$scriptName] - [public/Emojis] - Done" #endregion - From public/Emojis #region - From public/Markdown Write-Verbose "[$scriptName] - [public/Markdown] - Processing folder" #region - From public/Markdown/Get-GitHubMarkdown.ps1 Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdown.ps1] - Importing" filter Get-GitHubMarkdown { <# .NOTES https://docs.github.com/rest/reference/meta#github-api-root #> [CmdletBinding()] param ( [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [switch] $Text, [Parameter()] [ValidateSet('markdown', 'gfm')] [string] $Mode, [Parameter()] [string] $Context ) $body = @{ context = $Context mode = $Mode text = $Text } $inputObject = @{ APIEndpoint = '/markdown' Method = 'POST' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdown.ps1] - Done" #endregion - From public/Markdown/Get-GitHubMarkdown.ps1 #region - From public/Markdown/Get-GitHubMarkdownRaw.ps1 Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdownRaw.ps1] - Importing" filter Get-GitHubMarkdownRaw { <# .NOTES https://docs.github.com/rest/reference/meta#github-api-root #> [CmdletBinding()] param ( [Parameter()] [string] $Text ) $inputObject = @{ APIEndpoint = '/markdown/raw' ContentType = 'text/plain' Body = $Text Method = 'POST' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdownRaw.ps1] - Done" #endregion - From public/Markdown/Get-GitHubMarkdownRaw.ps1 Write-Verbose "[$scriptName] - [public/Markdown] - Done" #endregion - From public/Markdown #region - From public/Meta Write-Verbose "[$scriptName] - [public/Meta] - Processing folder" #region - From public/Meta/Get-GitHubApiVersions.ps1 Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubApiVersions.ps1] - Importing" filter Get-GitHubApiVersions { <# .SYNOPSIS Get all API versions. .DESCRIPTION Get all supported GitHub API versions. .EXAMPLE Get-GitHubApiVersions Get all supported GitHub API versions. .NOTES https://docs.github.com/rest/meta/meta#get-all-api-versions #> [OutputType([string[]])] [CmdletBinding()] param () $inputObject = @{ ApiEndpoint = '/versions' Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubApiVersions.ps1] - Done" #endregion - From public/Meta/Get-GitHubApiVersions.ps1 #region - From public/Meta/Get-GitHubMeta.ps1 Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubMeta.ps1] - Importing" filter Get-GitHubMeta { <# .SYNOPSIS Get GitHub meta information. .DESCRIPTION Returns meta information about GitHub, including a list of GitHub's IP addresses. For more information, see "[About GitHub's IP addresses](https://docs.github.com/articles/about-github-s-ip-addresses/)." The API's response also includes a list of GitHub's domain names. The values shown in the documentation's response are example values. You must always query the API directly to get the latest values. **Note:** This endpoint returns both IPv4 and IPv6 addresses. However, not all features support IPv6. You should refer to the specific documentation for each feature to determine if IPv6 is supported. .EXAMPLE Get-GitHubMeta Returns meta information about GitHub, including a list of GitHub's IP addresses. .NOTES https://docs.github.com/rest/meta/meta#get-apiname-meta-information #> [OutputType([object])] [CmdletBinding()] param () $inputObject = @{ ApiEndpoint = '/meta' Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubMeta.ps1] - Done" #endregion - From public/Meta/Get-GitHubMeta.ps1 #region - From public/Meta/Get-GitHubOctocat.ps1 Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubOctocat.ps1] - Importing" filter Get-GitHubOctocat { <# .SYNOPSIS Get Octocat. .DESCRIPTION Get the octocat as ASCII art. .EXAMPLE Get-GitHubOctocat Get the octocat as ASCII art .EXAMPLE Get-GitHubOctocat -S "Hello world" Get the octocat as ASCII art with a custom saying .NOTES https://docs.github.com/rest/meta/meta#get-octocat #> [OutputType([string])] [CmdletBinding()] param ( # The words to show in Octocat's speech bubble [Parameter()] [Alias('Say')] [Alias('Saying')] [string] $S ) $body = @{ s = $S } $inputObject = @{ APIEndpoint = '/octocat' Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubOctocat.ps1] - Done" #endregion - From public/Meta/Get-GitHubOctocat.ps1 #region - From public/Meta/Get-GitHubRoot.ps1 Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubRoot.ps1] - Importing" filter Get-GitHubRoot { <# .SYNOPSIS GitHub API Root. .DESCRIPTION Get Hypermedia links to resources accessible in GitHub's REST API. .EXAMPLE Get-GitHubRoot Get the root endpoint for the GitHub API. .NOTES https://docs.github.com/rest/meta/meta#github-api-root #> [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/' Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubRoot.ps1] - Done" #endregion - From public/Meta/Get-GitHubRoot.ps1 #region - From public/Meta/Get-GitHubZen.ps1 Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubZen.ps1] - Importing" filter Get-GitHubZen { <# .SYNOPSIS Get the Zen of GitHub. .DESCRIPTION Get a random sentence from the Zen of GitHub. .EXAMPLE Get-GitHubZen Get a random sentence from the Zen of GitHub. .NOTES https://docs.github.com/rest/meta/meta#get-the-zen-of-github #> [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/zen' Method = 'GET' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubZen.ps1] - Done" #endregion - From public/Meta/Get-GitHubZen.ps1 Write-Verbose "[$scriptName] - [public/Meta] - Done" #endregion - From public/Meta #region - From public/Organization Write-Verbose "[$scriptName] - [public/Organization] - Processing folder" #region - From public/Organization/Get-GitHubOrganization.ps1 Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganization.ps1] - Importing" filter Get-GitHubOrganization { <# .SYNOPSIS List organization .DESCRIPTION List organizations for the authenticated user - if no parameters are provided. List organizations for a user - if a username is provided. Lists all organizations, in the order that they were created on GitHub - if '-All' is provided. Get an organization - if a organization name is provided. .EXAMPLE Get-GitHubOrganization List organizations for the authenticated user. .EXAMPLE Get-GitHubOrganization -Username 'octocat' List public organizations for the user 'octocat'. .EXAMPLE Get-GitHubOrganization -All -Since 142951047 List organizations, starting with PSModule. .EXAMPLE Get-GitHubOrganization -Name 'PSModule' Get the organization 'PSModule'. .NOTES https://docs.github.com/rest/orgs/orgs #> [OutputType([pscustomobject])] [CmdletBinding(DefaultParameterSetName = '__DefaultSet')] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ParameterSetName = 'NamedOrg', ValueFromPipelineByPropertyName )] [Alias('login')] [Alias('org')] [Alias('owner')] [string] $OrganizationName, # The handle for the GitHub user account. [Parameter( Mandatory, ParameterSetName = 'NamedUser', ValueFromPipelineByPropertyName )] [string] $Username, # List all organizations. Use '-Since' to start at a specific organization id. [Parameter( Mandatory, ParameterSetName = 'AllOrg' )] [switch] $All, # A organization ID. Only return organizations with an ID greater than this ID. [Parameter(ParameterSetName = 'AllOrg')] [int] $Since = 0, # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllOrg')] [Parameter(ParameterSetName = 'UserOrg')] [Parameter(ParameterSetName = '__DefaultSet')] [int] $PerPage = 30 ) switch ($PSCmdlet.ParameterSetName) { '__DefaultSet' { Get-GitHubMyOrganization -PerPage $PerPage | Get-GitHubOrganizationByName } 'NamedOrg' { Get-GitHubOrganizationByName -OrganizationName $OrganizationName } 'NamedUser' { Get-GitHubUserOrganization -Username $Username } 'AllOrg' { Get-GitHubAllOrganization -Since $Since -PerPage $PerPage } } } Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganization.ps1] - Done" #endregion - From public/Organization/Get-GitHubOrganization.ps1 #region - From public/Organization/Get-GitHubOrganizationAppInstallation.ps1 Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganizationAppInstallation.ps1] - Importing" filter Get-GitHubOrganizationAppInstallation { <# .SYNOPSIS List app installations for an organization .DESCRIPTION Lists all GitHub Apps in an organization. The installation count includes all GitHub Apps installed on repositories in the organization. You must be an organization owner with `admin:read` scope to use this endpoint. .EXAMPLE Get-GitHubOrganizationAppInstallation -OrganizationName 'github' Gets all GitHub Apps in the organization `github`. .NOTES https://docs.github.com/rest/orgs/orgs#list-app-installations-for-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/installations" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response.installations } Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganizationAppInstallation.ps1] - Done" #endregion - From public/Organization/Get-GitHubOrganizationAppInstallation.ps1 #region - From public/Organization/Remove-GitHubOrganization.ps1 Write-Verbose "[$scriptName] - [public/Organization/Remove-GitHubOrganization.ps1] - Importing" filter Remove-GitHubOrganization { <# .SYNOPSIS Delete an organization .DESCRIPTION Deletes an organization and all its repositories. The organization login will be unavailable for 90 days after deletion. Please review the Terms of Service regarding account deletion before using this endpoint: https://docs.github.com/site-policy/github-terms/github-terms-of-service .EXAMPLE Remove-GitHubOrganization -OrganizationName 'github' Deletes the organization 'github' and all its repositories. .NOTES https://docs.github.com/rest/orgs/orgs#delete-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName ) $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName" Method = 'DELETE' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Organization/Remove-GitHubOrganization.ps1] - Done" #endregion - From public/Organization/Remove-GitHubOrganization.ps1 #region - From public/Organization/Set-GitHubOrganization.ps1 Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganization.ps1] - Importing" filter Set-GitHubOrganization { <# .SYNOPSIS Update an organization .DESCRIPTION **Parameter Deprecation Notice:** GitHub will replace and discontinue `members_allowed_repository_creation_type` in favor of more granular permissions. The new input parameters are `members_can_create_public_repositories`, `members_can_create_private_repositories` for all organizations and `members_can_create_internal_repositories` for organizations associated with an enterprise account using GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+. For more information, see the [blog post](https://developer.github.com/changes/2019-12-03-internal-visibility-changes). Enables an authenticated organization owner with the `admin:org` scope or the `repo` scope to update the organization's profile and member privileges. .EXAMPLE Set-GitHubOrganization -OrganizationName 'github' -Blog 'https://github.blog' Sets the blog URL for the organization 'github' to 'https://github.blog'. .EXAMPLE $param = @{ OrganizationName = 'github' MembersCanCreatePublicRepositories = $true MembersCanCreatePrivateRepositories = $true MembersCanCreateInternalRepositories = $true } Set-GitHubOrganization @param Sets the repository creation permissions for the organization 'github' to allow all members to create public, private, and internal repositories. .NOTES https://docs.github.com/rest/orgs/orgs#update-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # Billing email address. This address is not publicized. [Parameter(ValueFromPipelineByPropertyName)] [Alias('billing_email')] [string] $BillingEmail, # The company name. [Parameter(ValueFromPipelineByPropertyName)] [string] $Company, # The publicly visible email address. [Parameter(ValueFromPipelineByPropertyName)] [string] $Email, # The Twitter username of the company. [Parameter(ValueFromPipelineByPropertyName)] [Alias('twitter_username')] [string] $TwitterUsername, # The location. [Parameter(ValueFromPipelineByPropertyName)] [string] $Location, # The shorthand name of the company. [Parameter(ValueFromPipelineByPropertyName)] [string] $Name, # The description of the company. [Parameter(ValueFromPipelineByPropertyName)] [string] $Description, # Whether an organization can use organization projects. [Parameter(ValueFromPipelineByPropertyName)] [Alias('has_organization_projects')] [bool] $HasOrganizationProjects, # Whether repositories that belong to the organization can use repository projects. [Parameter(ValueFromPipelineByPropertyName)] [Alias('has_repository_projects')] [bool] $HasRepositoryProjects, # Default permission level members have for organization repositories. [Parameter(ValueFromPipelineByPropertyName)] [Alias('default_repository_permission')] [ValidateSet('read', 'write', 'admin', 'none')] [string] $DefaultRepositoryPermission, # Whether of non-admin organization members can create repositories. Note: A parameter can override this parameter. See members_allowed_repository_creation_type in this table for details. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_repositories')] [bool] $MembersCanCreateRepositories = $true, # Whether organization members can create internal repositories, which are visible to all enterprise members. You can only allow members to create internal repositories if your organization is associated with an enterprise account using GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+. For more information, see "Restricting repository creation in your organization" in the GitHub Help documentation. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_internal_repositories')] [bool] $MembersCanCreateInternalRepositories, # Whether organization members can create private repositories, which are visible to organization members with permission. For more information, see "Restricting repository creation in your organization" in the GitHub Help documentation. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_private_repositories')] [bool] $MembersCanCreatePrivateRepositories, # Whether organization members can create public repositories, which are visible to anyone. For more information, see "Restricting repository creation in your organization" in the GitHub Help documentation. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_public_repositories')] [bool] $MembersCanCreatePublicRepositories, # Specifies which types of repositories non-admin organization members can create. private is only available to repositories that are part of an organization on GitHub Enterprise Cloud. Note: This parameter is deprecated and will be removed in the future. Its return value ignores internal repositories. Using this parameter overrides values set in members_can_create_repositories. See the parameter deprecation notice in the operation description for details. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_allowed_repository_creation_type')] [ValidateSet('all', 'private', 'none')] [string] $MembersAllowedRepositoryCreationType, # Whether organization members can create GitHub Pages sites. Existing published sites will not be impacted. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_pages')] [bool] $MembersCanCreatePages = $true, # Whether organization members can create public GitHub Pages sites. Existing published sites will not be impacted. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_public_pages')] [bool] $MembersCanCreatePublicPages = $true, # Whether organization members can create private GitHub Pages sites. Existing published sites will not be impacted. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_create_private_pages')] [bool] $MembersCanCreatePrivatePages = $true, # Whether organization members can fork private organization repositories. [Parameter(ValueFromPipelineByPropertyName)] [Alias('members_can_fork_private_repositories')] [bool] $MembersCanForkPrivateRepositories = $false, # Whether contributors to organization repositories are required to sign off on commits they make through GitHub's web interface. [Parameter(ValueFromPipelineByPropertyName)] [Alias('web_commit_signoff_required')] [bool] $WebCommitSignoffRequired = $false, # Path to the organization's blog. [Parameter(ValueFromPipelineByPropertyName)] [string] $Blog, # Whether GitHub Advanced Security is automatically enabled for new repositories. # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization." # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request. [Parameter(ValueFromPipelineByPropertyName)] [Alias('advanced_security_enabled_for_new_repositories')] [bool] $AdvancedSecurityEnabledForNewRepositories = $false, # Whether Dependabot alerts is automatically enabled for new repositories. # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization." # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request. [Parameter(ValueFromPipelineByPropertyName)] [Alias('dependabot_alerts_enabled_for_new_repositories')] [bool] $DependabotAlertsEnabledForNewRepositories = $false, # Whether Dependabot security updates is automatically enabled for new repositories. # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization." # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request. [Parameter(ValueFromPipelineByPropertyName)] [Alias('dependabot_security_updates_enabled_for_new_repositories')] [bool] $DependabotSecurityUpdatesEnabledForNewRepositories = $false, # Whether dependency graph is automatically enabled for new repositories. # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization." # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request. [Parameter(ValueFromPipelineByPropertyName)] [Alias('dependency_graph_enabled_for_new_repositories')] [bool] $DependencyGraphEnabledForNewRepositories = $false, # Whether secret scanning is automatically enabled for new repositories. # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization." # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request. [Parameter(ValueFromPipelineByPropertyName)] [Alias('secret_scanning_enabled_for_new_repositories')] [bool] $SecretScanningEnabledForNewRepositories = $false, # Whether secret scanning push protection is automatically enabled for new repositories. # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization." # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request. [Parameter(ValueFromPipelineByPropertyName)] [Alias('secret_scanning_push_protection_enabled_for_new_repositories')] [bool] $SecretScanningPushProtectionEnabledForNewRepositories = $false, # Whether a custom link is shown to contributors who are blocked from pushing a secret by push protection. [Parameter(ValueFromPipelineByPropertyName)] [Alias('secret_scanning_push_protection_custom_link_enabled')] [bool] $SecretScanningPushProtectionCustomLinkEnabled = $false, # If secret_scanning_push_protection_custom_link_enabled is true, the URL that will be displayed to contributors who are blocked from pushing a secret. [Parameter(ValueFromPipelineByPropertyName)] [Alias('secret_scanning_push_protection_custom_link')] [string] $SecretScanningPushProtectionCustomLink ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashTableEntries -Hashtable $body -RemoveNames 'organization_name' $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName" Method = 'PATCH' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganization.ps1] - Done" #endregion - From public/Organization/Set-GitHubOrganization.ps1 #region - From public/Organization/Set-GitHubOrganizationSecurityFeature.ps1 Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganizationSecurityFeature.ps1] - Importing" filter Set-GitHubOrganizationSecurityFeature { <# .SYNOPSIS Enable or disable a security feature for an organization .DESCRIPTION Enables or disables the specified security feature for all eligible repositories in an organization. To use this endpoint, you must be an organization owner or be member of a team with the security manager role. A token with the 'write:org' scope is also required. GitHub Apps must have the `organization_administration:write` permission to use this endpoint. For more information, see "[Managing security managers in your organization](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)." .EXAMPLE Set-GitHubOrganizationSecurityFeature -OrganizationName 'github' -SecurityProduct 'dependency_graph' -Enablement 'enable_all' Enable the dependency graph for all repositories in the organization `github`. .NOTES https://docs.github.com/rest/orgs/orgs#enable-or-disable-a-security-feature-for-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The security feature to enable or disable. [Parameter(Mandatory)] [Alias('security_product')] [ValidateSet('dependency_graph', 'dependabot_alerts', 'dependabot_security_updates', 'advanced_security', 'code_scanning_default_setup', 'secret_scanning', 'secret_scanning_push_protection')] [string] $SecurityProduct, # The action to take. # enable_all means to enable the specified security feature for all repositories in the organization. disable_all means to disable the specified security feature for all repositories in the organization. [Parameter(Mandatory)] [ValidateSet('enable_all', 'disable_all')] [string] $Enablement, # CodeQL query suite to be used. If you specify the query_suite parameter, the default setup will be configured with this query suite only on all repositories that didn't have default setup already configured. It will not change the query suite on repositories that already have default setup configured. If you don't specify any query_suite in your request, the preferred query suite of the organization will be applied. [Parameter()] [Alias('query_suite')] [ValidateSet('default', 'extended')] [string] $QuerySuite ) $body = @{ query_suite = $QuerySuite } $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/$SecurityProduct/$Enablement" Method = 'POST' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganizationSecurityFeature.ps1] - Done" #endregion - From public/Organization/Set-GitHubOrganizationSecurityFeature.ps1 Write-Verbose "[$scriptName] - [public/Organization] - Done" #endregion - From public/Organization #region - From public/Status Write-Verbose "[$scriptName] - [public/Status] - Processing folder" #region - From public/Status/Get-GitHubScheduledMaintenance.ps1 Write-Verbose "[$scriptName] - [public/Status/Get-GitHubScheduledMaintenance.ps1] - Importing" function Get-GitHubScheduledMaintenance { <# .SYNOPSIS Gets the status of GitHub scheduled maintenance .DESCRIPTION Scheduled maintenances are planned outages, upgrades, or general notices that you're working on infrastructure and disruptions may occurr. A close sibling of Incidents, each usually goes through a progression of statuses listed below, with an impact calculated from a blend of component statuses (or an optional override). Status: Scheduled, In Progress, Verifying, or Completed Impact: None (black), Minor (yellow), Major (orange), or Critical (red) .EXAMPLE Get-GitHubScheduledMaintenance Get a list of the 50 most recent scheduled maintenances. This includes scheduled maintenances as described in the above two endpoints, as well as those in the Completed state. .EXAMPLE Get-GitHubScheduledMaintenance -Active Get a list of any active maintenances. .EXAMPLE Get-GitHubScheduledMaintenance -Upcoming Get a list of any upcoming maintenances. .NOTES https://www.githubstatus.com/api#scheduled-maintenances #> param( # Get a list of any active maintenances. # This endpoint will only return scheduled maintenances in the In Progress or Verifying state. [Parameter()] [switch] $Active, # Get a list of any upcoming maintenances. # This endpoint will only return scheduled maintenances still in the Scheduled state. [Parameter()] [switch] $Upcoming ) if ($Active) { $APIURI = 'https://www.githubstatus.com/api/v2/scheduled-maintenances/active.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.scheduled_maintenances return } if ($Upcoming) { $APIURI = 'https://www.githubstatus.com/api/v2/scheduled-maintenances/upcoming.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.scheduled_maintenances return } $APIURI = 'https://www.githubstatus.com/api/v2/scheduled-maintenances.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.scheduled_maintenances } Write-Verbose "[$scriptName] - [public/Status/Get-GitHubScheduledMaintenance.ps1] - Done" #endregion - From public/Status/Get-GitHubScheduledMaintenance.ps1 #region - From public/Status/Get-GitHubStatus.ps1 Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatus.ps1] - Importing" function Get-GitHubStatus { <# .SYNOPSIS Gets the status of GitHub services .DESCRIPTION Get a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances. Get the status rollup for the whole page. This endpoint includes an indicator - one of none, minor, major, or critical, as well as a human description of the blended component status. Examples of the blended status include "All Systems Operational", "Partial System Outage", and "Major Service Outage". .EXAMPLE Get-GitHubStatus Gets the status of GitHub services .EXAMPLE Get-GitHubStatus -Summary Gets a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances. .NOTES https://www.githubstatus.com/api#summary https://www.githubstatus.com/api#status #> [OutputType([pscustomobject])] [CmdletBinding()] param( # Gets a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances. [Parameter()] [switch] $Summary ) if ($Summary) { $APIURI = 'https://www.githubstatus.com/api/v2/summary.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response return } $APIURI = 'https://www.githubstatus.com/api/v2/status.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.status } Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatus.ps1] - Done" #endregion - From public/Status/Get-GitHubStatus.ps1 #region - From public/Status/Get-GitHubStatusComponents.ps1 Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusComponents.ps1] - Importing" function Get-GitHubStatusComponents { <# .SYNOPSIS Gets the status of GitHub components .DESCRIPTION Get the components for the page. Each component is listed along with its status - one of operational, degraded_performance, partial_outage, or major_outage. .EXAMPLE Get-GitHubStatusComponents Gets the status of GitHub components .NOTES https://www.githubstatus.com/api#components #> [OutputType([pscustomobject[]])] [CmdletBinding()] param() $APIURI = 'https://www.githubstatus.com/api/v2/components.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.components } Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusComponents.ps1] - Done" #endregion - From public/Status/Get-GitHubStatusComponents.ps1 #region - From public/Status/Get-GitHubStatusIncidents.ps1 Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusIncidents.ps1] - Importing" function Get-GitHubStatusIncidents { <# .SYNOPSIS Gets the status of GitHub incidents .DESCRIPTION Incidents are the cornerstone of any status page, being composed of many incident updates. Each incident usually goes through a progression of statuses listed below, with an impact calculated from a blend of component statuses (or an optional override). Status: Investigating, Identified, Monitoring, Resolved, or Postmortem Impact: None (black), Minor (yellow), Major (orange), or Critical (red) .EXAMPLE Get-GitHubStatusIncidents Gets the status of GitHub incidents .EXAMPLE Get-GitHubStatusIncidents -Unresolved Gets the status of GitHub incidents that are unresolved .NOTES https://www.githubstatus.com/api#incidents #> [OutputType([pscustomobject[]])] [CmdletBinding()] param( # Gets the status of GitHub incidents that are unresolved [Parameter()] [switch] $Unresolved ) if ($Unresolved) { $APIURI = 'https://www.githubstatus.com/api/v2/incidents/unresolved.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.incidents return } $APIURI = 'https://www.githubstatus.com/api/v2/incidents.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.incidents } Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusIncidents.ps1] - Done" #endregion - From public/Status/Get-GitHubStatusIncidents.ps1 Write-Verbose "[$scriptName] - [public/Status] - Done" #endregion - From public/Status #region - From public/Teams Write-Verbose "[$scriptName] - [public/Teams] - Processing folder" #region - From public/Teams/Get-GitHubRepoTeam.ps1 Write-Verbose "[$scriptName] - [public/Teams/Get-GitHubRepoTeam.ps1] - Importing" filter Get-GitHubRepoTeam { <# .NOTES https://docs.github.com/rest/reference/repos#get-a-repository #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubConfig -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubConfig -Name Repo) ) $inputObject = @{ Method = 'Get' APIEndpoint = "/repos/$Owner/$Repo/teams" } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Teams/Get-GitHubRepoTeam.ps1] - Done" #endregion - From public/Teams/Get-GitHubRepoTeam.ps1 Write-Verbose "[$scriptName] - [public/Teams] - Done" #endregion - From public/Teams #region - From public/Users Write-Verbose "[$scriptName] - [public/Users] - Processing folder" #region - From public/Users/Blocking Write-Verbose "[$scriptName] - [public/Users/Blocking] - Processing folder" #region - From public/Users/Blocking/Block-GitHubUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Blocking/Block-GitHubUser.ps1] - Importing" filter Block-GitHubUser { <# .SYNOPSIS Block a user from user or an organization. .DESCRIPTION Blocks the given user and returns true. If the user cannot be blocked false is returned. .EXAMPLE Block-GitHubUser -Username 'octocat' Blocks the user 'octocat' for the authenticated user. Returns $true if successful, $false if not. .EXAMPLE Block-GitHubUser -OrganizationName 'github' -Username 'octocat' Blocks the user 'octocat' from the organization 'github'. Returns $true if successful, $false if not. .NOTES https://docs.github.com/rest/users/blocking#block-a-user https://docs.github.com/rest/orgs/blocking#block-a-user-from-an-organization #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The organization name. The name is not case sensitive. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName ) if ($OrganizationName) { Block-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username } else { Block-GitHubUserByUser -Username $Username } } Write-Verbose "[$scriptName] - [public/Users/Blocking/Block-GitHubUser.ps1] - Done" #endregion - From public/Users/Blocking/Block-GitHubUser.ps1 #region - From public/Users/Blocking/Get-GitHubBlockedUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Blocking/Get-GitHubBlockedUser.ps1] - Importing" filter Get-GitHubBlockedUser { <# .SYNOPSIS List blocked users. .DESCRIPTION List the users that are blocked on your personal account or a given organization. .EXAMPLE Get-GitHubBlockedUser Returns a list of users blocked by the authenticated user. .EXAMPLE Get-GitHubBlockedUser -OrganizationName 'github' Lists all users blocked by the organization `github`. .NOTES https://docs.github.com/rest/users/blocking#list-users-blocked-by-the-authenticated-user https://docs.github.com/rest/orgs/blocking#list-users-blocked-by-an-organization #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) if ($OrganizationName) { Get-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -PerPage $PerPage } else { Get-GitHubBlockedUserByUser -PerPage $PerPage } } Write-Verbose "[$scriptName] - [public/Users/Blocking/Get-GitHubBlockedUser.ps1] - Done" #endregion - From public/Users/Blocking/Get-GitHubBlockedUser.ps1 #region - From public/Users/Blocking/Test-GitHubBlockedUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Blocking/Test-GitHubBlockedUser.ps1] - Importing" filter Test-GitHubBlockedUser { <# .SYNOPSIS Check if a user is blocked by the authenticated user or an organization. .DESCRIPTION Returns a 204 if the given user is blocked by the authenticated user or organization. Returns a 404 if the given user is not blocked, or if the given user account has been identified as spam by GitHub. .EXAMPLE Test-GitHubBlockedUser -Username 'octocat' Checks if the user `octocat` is blocked by the authenticated user. Returns true if the user is blocked, false if not. .EXAMPLE Test-GitHubBlockedUser -OrganizationName 'github' -Username 'octocat' Checks if the user `octocat` is blocked by the organization `github`. Returns true if the user is blocked, false if not. .NOTES https://docs.github.com/rest/users/blocking#check-if-a-user-is-blocked-by-the-authenticated-user https://docs.github.com/rest/orgs/blocking#check-if-a-user-is-blocked-by-an-organization #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The organization name. The name is not case sensitive. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) if ($OrganizationName) { Test-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -Username $Username -PerPage $PerPage } else { Test-GitHubBlockedUserByUser -Username $Username -PerPage $PerPage } } Write-Verbose "[$scriptName] - [public/Users/Blocking/Test-GitHubBlockedUser.ps1] - Done" #endregion - From public/Users/Blocking/Test-GitHubBlockedUser.ps1 #region - From public/Users/Blocking/Unblock-GitHubUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Blocking/Unblock-GitHubUser.ps1] - Importing" filter Unblock-GitHubUser { <# .SYNOPSIS Unblock a user .DESCRIPTION Unblocks the given user and returns true. .EXAMPLE Unblock-GitHubUser -Username 'octocat' Unblocks the user 'octocat' for the authenticated user. Returns $true if successful. .EXAMPLE Unblock-GitHubUser -OrganizationName 'github' -Username 'octocat' Unblocks the user 'octocat' from the organization 'github'. Returns $true if successful. .NOTES https://docs.github.com/rest/users/blocking#unblock-a-user https://docs.github.com/rest/orgs/blocking#unblock-a-user-from-an-organization #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The organization name. The name is not case sensitive. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('org')] [Alias('owner')] [Alias('login')] [string] $OrganizationName ) if ($OrganizationName) { Unblock-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username } else { Unblock-GitHubUserByUser -Username $Username } } Write-Verbose "[$scriptName] - [public/Users/Blocking/Unblock-GitHubUser.ps1] - Done" #endregion - From public/Users/Blocking/Unblock-GitHubUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Blocking] - Done" #endregion - From public/Users/Blocking #region - From public/Users/Emails Write-Verbose "[$scriptName] - [public/Users/Emails] - Processing folder" #region - From public/Users/Emails/Add-GitHubUserEmail.ps1 Write-Verbose "[$scriptName] - [public/Users/Emails/Add-GitHubUserEmail.ps1] - Importing" filter Add-GitHubUserEmail { <# .SYNOPSIS Add an email address for the authenticated user .DESCRIPTION This endpoint is accessible with the `user` scope. .EXAMPLE Add-GitHubUserEmail -Emails 'octocat@github.com','firstname.lastname@work.com' Adds the email addresses 'octocat@github.com' and 'firstname.lastname@work.com' to the authenticated user's account. .NOTES https://docs.github.com/rest/users/emails#add-an-email-address-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # Adds one or more email addresses to your GitHub account. # Must contain at least one email address. # Note: Alternatively, you can pass a single email address or an array of emails addresses directly, # but we recommend that you pass an object using the emails key. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string[]] $Emails ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/emails" Method = 'POST' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Emails/Add-GitHubUserEmail.ps1] - Done" #endregion - From public/Users/Emails/Add-GitHubUserEmail.ps1 #region - From public/Users/Emails/Get-GitHubUserEmail.ps1 Write-Verbose "[$scriptName] - [public/Users/Emails/Get-GitHubUserEmail.ps1] - Importing" filter Get-GitHubUserEmail { <# .SYNOPSIS List email addresses for the authenticated user .DESCRIPTION Lists all of your email addresses, and specifies which one is visible to the public. This endpoint is accessible with the `user:email` scope. Specifying '-Public' will return only the publicly visible email address, which you can set with the [Set primary email visibility for the authenticated user](https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user) endpoint. .EXAMPLE Get-GitHubUserEmail Gets all email addresses for the authenticated user. .EXAMPLE Get-GitHubUserEmail -Public Gets the publicly visible email address for the authenticated user. .NOTES https://docs.github.com/rest/users/emails#list-email-addresses-for-the-authenticated-user https://docs.github.com/en/rest/users/emails#list-public-email-addresses-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30, [Parameter()] [switch] $Public ) if ($Public) { Get-GitHubUserPublicEmail -PerPage $PerPage } else { Get-GitHubUserAllEmail -PerPage $PerPage } } Write-Verbose "[$scriptName] - [public/Users/Emails/Get-GitHubUserEmail.ps1] - Done" #endregion - From public/Users/Emails/Get-GitHubUserEmail.ps1 #region - From public/Users/Emails/Remove-GitHubUserEmail.ps1 Write-Verbose "[$scriptName] - [public/Users/Emails/Remove-GitHubUserEmail.ps1] - Importing" filter Remove-GitHubUserEmail { <# .SYNOPSIS Delete an email address for the authenticated user .DESCRIPTION This endpoint is accessible with the `user` scope. .EXAMPLE Remove-GitHubUserEmail -Emails 'octocat@github.com','firstname.lastname@work.com' Removes the email addresses 'octocat@github.com' and 'firstname.lastname@work.com' from the authenticated user's account. .NOTES https://docs.github.com/rest/users/emails#delete-an-email-address-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # Email addresses associated with the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string[]] $Emails ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/emails" Method = 'DELETE' Body = $body } $null = (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Emails/Remove-GitHubUserEmail.ps1] - Done" #endregion - From public/Users/Emails/Remove-GitHubUserEmail.ps1 #region - From public/Users/Emails/Set-GitHubUserEmailVisibility.ps1 Write-Verbose "[$scriptName] - [public/Users/Emails/Set-GitHubUserEmailVisibility.ps1] - Importing" filter Set-GitHubUserEmailVisibility { <# .SYNOPSIS Set primary email visibility for the authenticated user .DESCRIPTION Sets the visibility for your primary email addresses. .EXAMPLE Set-GitHubUserEmailVisibility -Visibility public Sets the visibility for your primary email addresses to public. .EXAMPLE Set-GitHubUserEmailVisibility -Visibility private Sets the visibility for your primary email addresses to private. .NOTES https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # Denotes whether an email is publicly visible. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateSet('public', 'private')] [string] $Visibility ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/email/visibility" Method = 'PATCH' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Emails/Set-GitHubUserEmailVisibility.ps1] - Done" #endregion - From public/Users/Emails/Set-GitHubUserEmailVisibility.ps1 Write-Verbose "[$scriptName] - [public/Users/Emails] - Done" #endregion - From public/Users/Emails #region - From public/Users/Followers Write-Verbose "[$scriptName] - [public/Users/Followers] - Processing folder" #region - From public/Users/Followers/Add-GitHubUserFollowing.ps1 Write-Verbose "[$scriptName] - [public/Users/Followers/Add-GitHubUserFollowing.ps1] - Importing" filter Add-GitHubUserFollowing { <# .SYNOPSIS Follow a user .DESCRIPTION Note that you'll need to set `Content-Length` to zero when calling out to this endpoint. For more information, see "[HTTP verbs](https://docs.github.com/rest/overview/resources-in-the-rest-api#http-verbs)." Following a user requires the user to be logged in and authenticated with basic auth or OAuth with the `user:follow` scope. .EXAMPLE Follow-GitHubUser -Username 'octocat' Follows the user with the username 'octocat'. .NOTES https://docs.github.com/rest/users/followers#follow-a-user #> [OutputType([pscustomobject])] [Alias('Follow-GitHubUser')] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/following/$Username" Method = 'PUT' } $null = (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Followers/Add-GitHubUserFollowing.ps1] - Done" #endregion - From public/Users/Followers/Add-GitHubUserFollowing.ps1 #region - From public/Users/Followers/Get-GitHubUserFollowers.ps1 Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowers.ps1] - Importing" filter Get-GitHubUserFollowers { <# .SYNOPSIS List followers of a given user or the authenticated user .DESCRIPTION Lists the people following a given user or the authenticated user. .EXAMPLE Get-GitHubUserFollowers Gets all followers of the authenticated user. .EXAMPLE Get-GitHubUserFollowers -Username 'octocat' Gets all followers of the user 'octocat'. .NOTES https://docs.github.com/rest/users/followers#list-followers-of-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserFollowersOfUser -Username $Username -PerPage $PerPage } else { Get-GitHubUserMyFollowers -PerPage $PerPage } } Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowers.ps1] - Done" #endregion - From public/Users/Followers/Get-GitHubUserFollowers.ps1 #region - From public/Users/Followers/Get-GitHubUserFollowing.ps1 Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowing.ps1] - Importing" filter Get-GitHubUserFollowing { <# .SYNOPSIS List the people a given user or the authenticated user follows .DESCRIPTION Lists the people who a given user or the authenticated user follows. .EXAMPLE Get-GitHubUserFollowing Gets all people the authenticated user follows. .EXAMPLE Get-GitHubUserFollowing -Username 'octocat' Gets all people that 'octocat' follows. .NOTES https://docs.github.com/rest/users/followers#list-the-people-the-authenticated-user-follows https://docs.github.com/rest/users/followers#list-the-people-a-user-follows #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserFollowingUser -Username $Username -PerPage $PerPage } else { Get-GitHubUserFollowingMe -PerPage $PerPage } } Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowing.ps1] - Done" #endregion - From public/Users/Followers/Get-GitHubUserFollowing.ps1 #region - From public/Users/Followers/Remove-GitHubUserFollowing.ps1 Write-Verbose "[$scriptName] - [public/Users/Followers/Remove-GitHubUserFollowing.ps1] - Importing" filter Remove-GitHubUserFollowing { <# .SYNOPSIS Unfollow a user .DESCRIPTION Unfollowing a user requires the user to be logged in and authenticated with basic auth or OAuth with the `user:follow` scope. .EXAMPLE Unfollow-GitHubUser -Username 'octocat' Unfollows the user with the username 'octocat'. .NOTES https://docs.github.com/rest/users/followers#unfollow-a-user #> [OutputType([pscustomobject])] [Alias('Unfollow-GitHubUser')] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/following/$Username" Method = 'DELETE' } $null = (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Followers/Remove-GitHubUserFollowing.ps1] - Done" #endregion - From public/Users/Followers/Remove-GitHubUserFollowing.ps1 #region - From public/Users/Followers/Test-GitHubUserFollows.ps1 Write-Verbose "[$scriptName] - [public/Users/Followers/Test-GitHubUserFollows.ps1] - Importing" filter Test-GitHubUserFollows { <# .SYNOPSIS Check if a given user or the authenticated user follows a person .DESCRIPTION Returns a 204 if the given user or the authenticated user follows another user. Returns a 404 if the user is not followed by a given user or the authenticated user. .EXAMPLE Test-GitHubUserFollows -Follows 'octocat' Test-GitHubUserFollows 'octocat' Checks if the authenticated user follows the user 'octocat'. .EXAMPLE Test-GitHubUserFollows -Username 'octocat' -Follows 'ratstallion' Checks if the user 'octocat' follows the user 'ratstallion'. .NOTES https://docs.github.com/rest/users/followers#check-if-a-person-is-followed-by-the-authenticated-user https://docs.github.com/rest/users/followers#check-if-a-user-follows-another-user #> [OutputType([bool])] [CmdletBinding()] param ( # The handle for the GitHub user account we want to check if is being followed. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Follows, # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Username ) if ($Username) { Test-GitHubUserFollowedByUser -Username $Username -Follows $Follows } else { Test-GitHubUserFollowedByMe -Username $Follows } } Write-Verbose "[$scriptName] - [public/Users/Followers/Test-GitHubUserFollows.ps1] - Done" #endregion - From public/Users/Followers/Test-GitHubUserFollows.ps1 Write-Verbose "[$scriptName] - [public/Users/Followers] - Done" #endregion - From public/Users/Followers #region - From public/Users/GPG-Keys Write-Verbose "[$scriptName] - [public/Users/GPG-Keys] - Processing folder" #region - From public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1 Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1] - Importing" filter Add-GitHubUserGpgKey { <# .SYNOPSIS Create a GPG key for the authenticated user .DESCRIPTION Adds a GPG key to the authenticated user's GitHub account. Requires that you are authenticated via Basic Auth, or OAuth with at least `write:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Add-GitHubUserGpgKey -Name 'GPG key for GitHub' -ArmoredPublicKey '-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1\n\nmQINBFnZ2ZIBEADQ2Z7Z7\n-----END PGP PUBLIC KEY BLOCK-----' Adds a GPG key to the authenticated user's GitHub account. .NOTES https://docs.github.com/rest/users/gpg-keys#create-a-gpg-key-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # A descriptive name for the new key. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Name, # A GPG key in ASCII-armored format. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [Alias('armored_public_key')] [string] $ArmoredPublicKey ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = "/user/gpg_keys" Method = 'POST' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1] - Done" #endregion - From public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1 #region - From public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1 Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1] - Importing" filter Get-GitHubUserGpgKey { <# .SYNOPSIS List GPG keys for a given user or the authenticated user .DESCRIPTION Lists a given user's or the current user's GPG keys. .EXAMPLE Get-GitHubUserGpgKey Gets all GPG keys for the authenticated user. .EXAMPLE Get-GitHubUserGpgKey -Username 'octocat' Gets all GPG keys for the 'octocat' user. .NOTES https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Username' )] [string] $Username, # The ID of the GPG key. [Parameter( ParameterSetName = 'Me' )] [Alias('gpg_key_id')] [string] $ID, # The number of results per page (max 100). [Parameter()] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserGpgKeyForUser -Username $Username -PerPage $PerPage } else { if ($ID) { Get-GitHubUserMyGpgKeyById -ID $ID } else { Get-GitHubUserMyGpgKey -PerPage $PerPage } } } Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1] - Done" #endregion - From public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1 #region - From public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1 Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1] - Importing" filter Remove-GitHubUserGpgKey { <# .SYNOPSIS Delete a GPG key for the authenticated user .DESCRIPTION Removes a GPG key from the authenticated user's GitHub account. Requires that you are authenticated via Basic Auth or via OAuth with at least `admin:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Remove-GitHubUserGpgKey -ID '1234567' Gets the GPG key with ID '1234567' for the authenticated user. .NOTES https://docs.github.com/rest/users/gpg-keys#delete-a-gpg-key-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The ID of the GPG key. [Parameter( Mandatory )] [Alias('gpg_key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/gpg_keys/$ID" Method = 'DELETE' } $null = (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1] - Done" #endregion - From public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1 Write-Verbose "[$scriptName] - [public/Users/GPG-Keys] - Done" #endregion - From public/Users/GPG-Keys #region - From public/Users/Social-Accounts Write-Verbose "[$scriptName] - [public/Users/Social-Accounts] - Processing folder" #region - From public/Users/Social-Accounts/Add-GitHubUserSocials.ps1 Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Add-GitHubUserSocials.ps1] - Importing" filter Add-GitHubUserSocials { <# .SYNOPSIS Add social accounts for the authenticated user .DESCRIPTION Add one or more social accounts to the authenticated user's profile. This endpoint is accessible with the `user` scope. .EXAMPLE Add-GitHubUserSocials -AccountUrls 'https://twitter.com/MyTwitterAccount', 'https://www.linkedin.com/company/MyCompany' Adds the Twitter and LinkedIn accounts to the authenticated user's profile. .NOTES https://docs.github.com/rest/users/social-accounts#add-social-accounts-for-the-authenticated-user #> [OutputType([void])] [CmdletBinding()] param ( # Full URLs for the social media profiles to add. [Parameter(Mandatory)] [Alias('account_urls')] [string[]] $AccountUrls ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/social_accounts' Body = $body Method = 'POST' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Add-GitHubUserSocials.ps1] - Done" #endregion - From public/Users/Social-Accounts/Add-GitHubUserSocials.ps1 #region - From public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1 Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1] - Importing" filter Remove-GitHubUserSocials { <# .SYNOPSIS Delete social accounts for the authenticated user .DESCRIPTION Deletes one or more social accounts from the authenticated user's profile. This endpoint is accessible with the `user` scope. .PARAMETER AccountUrls Parameter description .EXAMPLE Remove-GitHubUserSocials -AccountUrls 'https://twitter.com/MyTwitterAccount' .NOTES https://docs.github.com/rest/users/social-accounts#delete-social-accounts-for-the-authenticated-user #> [OutputType([void])] [CmdletBinding()] param ( # Full URLs for the social media profiles to add. [Parameter(Mandatory)] [Alias('account_urls')] [string[]] $AccountUrls ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/social_accounts' Body = $body Method = 'DELETE' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1] - Done" #endregion - From public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1 Write-Verbose "[$scriptName] - [public/Users/Social-Accounts] - Done" #endregion - From public/Users/Social-Accounts #region - From public/Users/Get-GitHubUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUser.ps1] - Importing" filter Get-GitHubUser { <# .SYNOPSIS List user(s) .DESCRIPTION Get the authenticated user - if no parameters are provided. Get a given user - if a username is provided. Lists all users, in the order that they signed up on GitHub - if '-All' is provided. .EXAMPLE Get-GitHubUser Get the authenticated user. .EXAMPLE Get-GitHubUser -Username 'octocat' Get the 'octocat' user. .EXAMPLE Get-GitHubUser -All -Since 17722253 Get a list of users, starting with the user 'MariusStorhaug'. .NOTES https://docs.github.com/rest/users/users #> [OutputType([pscustomobject])] [CmdletBinding(DefaultParameterSetName = '__DefaultSet')] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ParameterSetName = 'NamedUser', ValueFromPipelineByPropertyName )] [string] $Username, # List all users. Use '-Since' to start at a specific user id. [Parameter( Mandatory, ParameterSetName = 'AllUsers' )] [switch] $All, # A user ID. Only return users with an ID greater than this ID. [Parameter(ParameterSetName = 'AllUsers')] [int] $Since = 0, # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllUsers')] [int] $PerPage = 30 ) switch ($PSCmdlet.ParameterSetName) { '__DefaultSet' { $user = Get-GitHubMyUser $social_accounts = Get-GitHubMyUserSocials $user | Add-Member -MemberType NoteProperty -Name 'social_accounts' -Value $social_accounts -Force $user } 'NamedUser' { $user = Get-GitHubUserByName -Username $Username $social_accounts = Get-GitHubUserSocialsByName -Username $Username $user | Add-Member -MemberType NoteProperty -Name 'social_accounts' -Value $social_accounts -Force $user } 'AllUsers' { Get-GitHubAllUsers -Since $Since -PerPage $PerPage } } } Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUser.ps1] - Done" #endregion - From public/Users/Get-GitHubUser.ps1 #region - From public/Users/Get-GitHubUserCard.ps1 Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUserCard.ps1] - Importing" filter Get-GitHubUserCard { <# .SYNOPSIS Get contextual information for a user .DESCRIPTION Provides hovercard information when authenticated through basic auth or OAuth with the `repo` scope. You can find out more about someone in relation to their pull requests, issues, repositories, and organizations. The `subject_type` and `subject_id` parameters provide context for the person's hovercard, which returns more information than without the parameters. For example, if you wanted to find out more about `octocat` who owns the `Spoon-Knife` repository via cURL, it would look like this: ```shell curl -u username:token https://api.github.com/users/octocat/hovercard?subject_type=repository&subject_id=1300192 ``` .EXAMPLE .NOTES https://docs.github.com/rest/users/users#get-contextual-information-for-a-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Username, [Parameter()] [ValidateSet('organization', 'repository', 'issue', 'pull_request')] [string] $SubjectType, [Parameter()] [int] $SubjectID = '' ) $body = @{ subject_type = $SubjectType subject_id = $SubjectID } $inputObject = @{ APIEndpoint = "/users/$Username/hovercard" Method = 'GET' Body = $body } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUserCard.ps1] - Done" #endregion - From public/Users/Get-GitHubUserCard.ps1 #region - From public/Users/Set-GitHubUser.ps1 Write-Verbose "[$scriptName] - [public/Users/Set-GitHubUser.ps1] - Importing" filter Set-GitHubUser { <# .SYNOPSIS Update the authenticated user .DESCRIPTION **Note:** If your email is set to private and you send an `email` parameter as part of this request to update your profile, your privacy settings are still enforced: the email address will not be displayed on your public profile or via the API. .EXAMPLE Set-GitHubUser -Name 'octocat' Update the authenticated user's name to 'octocat' .EXAMPLE Set-GitHubUser -Location 'San Francisco' Update the authenticated user's location to 'San Francisco' .EXAMPLE Set-GitHubUser -Hireable $true -Bio 'I love programming' Update the authenticated user's hiring availability to 'true' and their biography to 'I love programming' .NOTES https://docs.github.com/rest/users/users#update-the-authenticated-user #> [OutputType([void])] [Alias('Update-GitHubUser')] [CmdletBinding()] param ( # The new name of the user. [Parameter()] [string] $Name, # The publicly visible email address of the user. [Parameter()] [string] $Email, # The new blog URL of the user. [Parameter()] [string] $Blog, # The new Twitter username of the user. [Parameter()] [string] $TwitterUsername, # The new company of the user. [Parameter()] [string] $Company, # The new location of the user. [Parameter()] [string] $Location, # The new hiring availability of the user. [Parameter()] [boolean] $Hireable, # The new short biography of the user. [Parameter()] [string] $Bio ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user' Body = $body Method = 'PATCH' } (Invoke-GitHubAPI @inputObject).Response } Write-Verbose "[$scriptName] - [public/Users/Set-GitHubUser.ps1] - Done" #endregion - From public/Users/Set-GitHubUser.ps1 Write-Verbose "[$scriptName] - [public/Users] - Done" #endregion - From public/Users Write-Verbose "[$scriptName] - [public] - Done" #endregion - From public #region - From GitHub.ps1 Write-Verbose "[$scriptName] - [GitHub.ps1] - Importing" $scriptFilePath = $MyInvocation.MyCommand.Path Write-Verbose "[$scriptFilePath] - Initializing GitHub module..." Initialize-SecretVault -Name $script:SecretVault.Name -Type $script:SecretVault.Type # Autologon if a token is present in environment variables $envVar = Get-ChildItem -Path 'Env:' | Where-Object Name -In 'GH_TOKEN', 'GITHUB_TOKEN' | Select-Object -First 1 $envVarPresent = $envVar.count -gt 0 if ($envVarPresent) { Connect-GitHubAccount } Write-Verbose "[$scriptName] - [GitHub.ps1] - Done" #endregion - From GitHub.ps1 Export-ModuleMember -Function 'Disable-GitHubWorkflow','Enable-GitHubWorkflow','Get-GitHubWorkflow','Get-GitHubWorkflowRun','Get-GitHubWorkflowUsage','Remove-GitHubWorkflowRun','Start-GitHubWorkflow','Start-GitHubWorkflowReRun','Stop-GitHubWorkflowRun','Invoke-GitHubAPI','Connect-GitHubAccount','Disconnect-GitHubAccount','Get-GitHubRepoBranch','Get-GitHubConfig','Set-GitHubConfig','Get-GitHubEnvironment','Get-GitHubEnvironmentSecrets','Update-GitHubEnvironment','Get-GitHubEmojis','Get-GitHubMarkdown','Get-GitHubMarkdownRaw','Get-GitHubApiVersions','Get-GitHubMeta','Get-GitHubOctocat','Get-GitHubRoot','Get-GitHubZen','Get-GitHubOrganization','Get-GitHubOrganizationAppInstallation','Remove-GitHubOrganization','Set-GitHubOrganization','Set-GitHubOrganizationSecurityFeature','Get-GitHubScheduledMaintenance','Get-GitHubStatus','Get-GitHubStatusComponents','Get-GitHubStatusIncidents','Get-GitHubRepoTeam','Block-GitHubUser','Get-GitHubBlockedUser','Test-GitHubBlockedUser','Unblock-GitHubUser','Add-GitHubUserEmail','Get-GitHubUserEmail','Remove-GitHubUserEmail','Set-GitHubUserEmailVisibility','Add-GitHubUserFollowing','Get-GitHubUserFollowers','Get-GitHubUserFollowing','Remove-GitHubUserFollowing','Test-GitHubUserFollows','Add-GitHubUserGpgKey','Get-GitHubUserGpgKey','Remove-GitHubUserGpgKey','Add-GitHubUserSocials','Remove-GitHubUserSocials','Get-GitHubUser','Get-GitHubUserCard','Set-GitHubUser' -Cmdlet '' -Variable '' -Alias '*' |