GitHub.psm1
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains long links.')] [CmdletBinding()] param() $scriptName = 'GitHub' Write-Verbose "[$scriptName] - Importing module" #region - From [classes] - [public] Write-Verbose "[$scriptName] - [classes] - [public] - Processing folder" #region - From [classes] - [public] - [GitHubContext] Write-Verbose "[$scriptName] - [classes] - [public] - [GitHubContext] - Importing" class GitHubContext { # The API base URI. # https://api.github.com [string] $ApiBaseUri # The GitHub API version. # 2022-11-28 [string] $ApiVersion # The authentication client ID. # Client ID for UAT [string] $AuthClientID # The authentication type. # UAT / PAT / App / IAT [string] $AuthType # Client ID for GitHub Apps [string] $ClientID # The device flow type. # GitHubApp / OAuthApp [string] $DeviceFlowType # The API hostname. # github.com / msx.ghe.com / github.local [string] $HostName # User ID / App ID as GraphQL Node ID [string] $NodeID # The Database ID of the context. [string] $DatabaseID # The context ID. # HostName/Username or HostName/AppSlug # Context:PSModule.Github/github.com/Octocat [string] $ID # The user name. [string] $UserName # The default value for the Owner parameter. [string] $Owner # The default value for the Repo parameter. [string] $Repo # The scope when authenticating with OAuth. # 'gist read:org repo workflow' [string] $Scope # The token type. # ghu / gho / ghp / github_pat / PEM / ghs / [string] $TokenType # The access token. [securestring] $Token # The token expiration date. # 2024-01-01-00:00:00 [datetime] $TokenExpirationDate # The refresh token. [securestring] $RefreshToken # The refresh token expiration date. # 2024-01-01-00:00:00 [datetime] $RefreshTokenExpirationDate GitHubContext([string]$ID) { $this.ID = $ID } GitHubContext([hashtable]$Properties) { foreach ($Property in $Properties.Keys) { $this.$Property = $Properties.$Property } } GitHubContext([PSCustomObject]$Object) { $Object.PSObject.Properties | ForEach-Object { $this.($_.Name) = $_.Value } } } Write-Verbose "[$scriptName] - [classes] - [public] - [GitHubContext] - Done" #endregion - From [classes] - [public] - [GitHubContext] Write-Verbose "[$scriptName] - [classes] - [public] - Done" #endregion - From [classes] - [public] #region - From [functions] - [private] Write-Verbose "[$scriptName] - [functions] - [private] - Processing folder" #region - From [functions] - [private] - [Auth] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - Processing folder" #region - From [functions] - [private] - [Auth] - [DeviceFlow] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - Processing folder" #region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin] - 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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Is the CLI part of the module.')] [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 host to connect to. [Parameter(Mandatory)] [string] $HostName, # The refresh token to use for re-authentication. [Parameter()] [securestring] $RefreshToken ) do { if ($RefreshToken) { $tokenResponse = Wait-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken -HostName $HostName } else { $deviceCodeResponse = Request-GitHubDeviceCode -ClientID $ClientID -Scope $Scope -HostName $HostName $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 $HostName in your browser..." Start-Process $verificationUri $tokenResponse = Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval -HostName $HostName } } while ($tokenResponse.error) $tokenResponse } Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin] - Done" #endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin] #region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken] - 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 -HostName 'github.com' 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, # The host to connect to. [Parameter(Mandatory)] [string] $HostName ) $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://$HostName/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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken] - Done" #endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken] #region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode] - Importing" function Request-GitHubDeviceCode { <# .SYNOPSIS Request a GitHub Device Code. .DESCRIPTION Request a GitHub Device Code. .EXAMPLE Request-GitHubDeviceCode -ClientID $ClientID -Mode $Mode -HostName 'github.com' 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', # The host to connect to. [Parameter(Mandatory)] [string] $HostName ) $headers = @{ Accept = 'application/json' } $body = @{ client_id = $ClientID scope = $Scope } $RESTParams = @{ Uri = "https://$HostName/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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode] - Done" #endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode] #region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired] - 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. #> [OutputType([bool])] [CmdletBinding()] param( [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $contextObj = Get-GitHubContext -Context $Context $tokenExpirationDate = $contextObj.TokenExpirationDate $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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired] - Done" #endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired] #region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken] - 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 host to connect to. [Parameter(Mandatory)] [string] $HostName, # The interval to wait between polling for the token. [Parameter()] [int] $Interval = 5 ) do { if ($RefreshToken) { $response = Request-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken -HostName $HostName } else { $response = Request-GitHubAccessToken -ClientID $ClientID -DeviceCode $DeviceCode -HostName $HostName } 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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken] - Done" #endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - Done" #endregion - From [functions] - [private] - [Auth] - [DeviceFlow] Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - Done" #endregion - From [functions] - [private] - [Auth] #region - From [functions] - [private] - [Commands] Write-Verbose "[$scriptName] - [functions] - [private] - [Commands] - Processing folder" #region - From [functions] - [private] - [Commands] - [ConvertFrom-GitHubOutput] Write-Verbose "[$scriptName] - [functions] - [private] - [Commands] - [ConvertFrom-GitHubOutput] - Importing" filter ConvertFrom-GitHubOutput { <# .SYNOPSIS Gets the GitHub output. .DESCRIPTION Gets the GitHub output from $env:GITHUB_OUTPUT and creates an object with key-value pairs, supporting both single-line and multi-line values, and parsing JSON values. .EXAMPLE $content = @' zen=something else result={"MyOutput":"Hello, World!","Status":"Success"} MY_VALUE<<EOF_12a089b9-051e-4c4e-91c9-8e24fc2fbbf6 Line1 Line2 Line3 EOF_12a089b9-051e-4c4e-91c9-8e24fc2fbbf6 Config={"Nested":{"SubSetting":"SubValue"},"Setting1":"Value1","Setting2":2} Numbers=12345 '@ $content | ConvertFrom-GitHubOutput zen : something else result : @{MyOutput=Hello, World!; Status=Success} MY_VALUE : Line1 Line2 Line3 Config : {[Nested, System.Collections.Hashtable], [Setting1, Value1], [Setting2, 2]} Numbers : 12345 This will convert the GitHub Actions output syntax to a PowerShell object. #> [OutputType([pscustomobject])] [OutputType([hashtable])] [CmdletBinding()] param( # The input data to convert [Parameter( Mandatory, ValueFromPipeline )] [string[]] $InputData, # Whether to convert the input data to a hashtable [switch] $AsHashtable ) begin { $lines = @() } process { foreach ($item in $InputData) { if ($item -is [string]) { $lines += $item -split "`n" } } } end { # Initialize variables $result = @{} $i = 0 while ($i -lt $lines.Count) { $line = $lines[$i].Trim() Write-Debug "[$line]" # Skip empty or delimiter lines if ($line -match '^-+$' -or [string]::IsNullOrWhiteSpace($line)) { Write-Debug "[$line] - Skipping empty line" $i++ continue } # Check for key=value pattern if ($line -match '^([^=]+)=(.*)$') { Write-Debug "[$line] - key=value pattern" $key = $Matches[1].Trim() $value = $Matches[2] # Attempt to parse JSON if (Test-Json $value -ErrorAction SilentlyContinue) { Write-Debug "[$line] - value is JSON" $value = ConvertFrom-Json $value -AsHashtable:$AsHashtable } $result[$key] = $value $i++ continue } # Check for key<<EOF pattern if ($line -match '^([^<]+)<<(\S+)$') { Write-Debug "[$line] - key<<EOF pattern" $key = $Matches[1].Trim() $eof_marker = $Matches[2] Write-Debug "[$line] - key<<EOF pattern - [$eof_marker]" $i++ $value_lines = @() while ($i -lt $lines.Count -and $lines[$i] -ne $eof_marker) { $valueItem = $lines[$i].Trim() Write-Debug "[$line] - key<<EOF pattern - [$eof_marker] - [$valueItem]" $value_lines += $valueItem $i++ } # Skip the EOF marker if ($i -lt $lines.Count -and $lines[$i] -eq $eof_marker) { Write-Debug "[$line] - key<<EOF pattern - Closing" $i++ } $value = $value_lines -join "`n" if (Test-Json $value -ErrorAction SilentlyContinue) { Write-Debug "[$line] - key<<EOF pattern - value is JSON" $value = ConvertFrom-Json $value -AsHashtable:$AsHashtable } $result[$key] = $value continue } $i++ } if ($AsHashtable) { return $result } [PSCustomObject]$result } } Write-Verbose "[$scriptName] - [functions] - [private] - [Commands] - [ConvertFrom-GitHubOutput] - Done" #endregion - From [functions] - [private] - [Commands] - [ConvertFrom-GitHubOutput] #region - From [functions] - [private] - [Commands] - [ConvertTo-GitHubOutput] Write-Verbose "[$scriptName] - [functions] - [private] - [Commands] - [ConvertTo-GitHubOutput] - Importing" filter ConvertTo-GitHubOutput { <# .SYNOPSIS Converts a PowerShell object's properties to expected format for GitHub Actions output syntax. .DESCRIPTION The function iterates over each property of the provided PowerShell object and writes them to a specified file in the format used by GitHub Actions for outputs. It supports: - Single-line values (written as key=value). - Multi-line string values (using key<<EOF syntax with a unique EOF marker). - Converts hashtables and PSCustomObject values to compressed JSON strings. .EXAMPLE $object = [PSCustomObject]@{ zen = 'something else' result = [PSCustomObject]@{ MyOutput = "Hello, World!"; Status = "Success" } MY_VALUE = "Line1`nLine2`nLine3" Config = @{ Setting1 = "Value1"; Setting2 = 2; Nested = @{ SubSetting = "SubValue" } } Numbers = 12345 } $object | ConvertTo-GitHubOutput zen=something else result={"MyOutput":"Hello, World!","Status":"Success"} MY_VALUE<<EOF_12a089b9-051e-4c4e-91c9-8e24fc2fbbf6 Line1 Line2 Line3 EOF_12a089b9-051e-4c4e-91c9-8e24fc2fbbf6 Config={"Nested":{"SubSetting":"SubValue"},"Setting1":"Value1","Setting2":2} Numbers=12345 This will convert the properties of $object to GitHub Actions output syntax. #> [OutputType([string])] [CmdletBinding()] param( # The PowerShell object containing the key-value pairs to be saved. # Each property of the object represents a key. [Parameter( Mandatory, ValueFromPipeline )] [object] $InputObject ) $outputLines = @() if ($InputObject -is [hashtable]) { $InputObject = [PSCustomObject]$InputObject } foreach ($property in $InputObject.PSObject.Properties) { $key = $property.Name $value = $property.Value # Convert hashtable or PSCustomObject to compressed JSON if ($value -is [hashtable] -or $value -is [PSCustomObject]) { $value = $value | ConvertTo-Json -Compress } if ($value -is [string] -and $value.Contains("`n")) { # Multi-line value $guid = [Guid]::NewGuid().ToString() $EOFMarker = "EOF_$guid" $outputLines += "$key<<$EOFMarker" $outputLines += $value $outputLines += $EOFMarker } else { # Single-line value $outputLines += "$key=$value" } } $outputLines } Write-Verbose "[$scriptName] - [functions] - [private] - [Commands] - [ConvertTo-GitHubOutput] - Done" #endregion - From [functions] - [private] - [Commands] - [ConvertTo-GitHubOutput] Write-Verbose "[$scriptName] - [functions] - [private] - [Commands] - Done" #endregion - From [functions] - [private] - [Commands] #region - From [functions] - [private] - [Gitignore] Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - Processing folder" #region - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName] - Importing" filter Get-GitHubGitignoreByName { <# .SYNOPSIS Get a gitignore template .DESCRIPTION The API also allows fetching the source of a single template. Use the raw [media type](https://docs.github.com/rest/overview/media-types/) to get the raw contents. .EXAMPLE Get-GitHubGitignoreList Get all gitignore templates .NOTES https://docs.github.com/rest/gitignore/gitignore#get-a-gitignore-template #> [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string] $Name ) process { $inputObject = @{ APIEndpoint = "/gitignore/templates/$Name" Accept = 'application/vnd.github.raw+json' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName] - Done" #endregion - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName] #region - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList] Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList] - Importing" filter Get-GitHubGitignoreList { <# .SYNOPSIS Get all gitignore templates .DESCRIPTION List all templates available to pass as an option when [creating a repository](https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user). .EXAMPLE Get-GitHubGitignoreList Get all gitignore templates .NOTES https://docs.github.com/rest/gitignore/gitignore#get-all-gitignore-templates #> [OutputType([string[]])] [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/gitignore/templates' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList] - Done" #endregion - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList] Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - Done" #endregion - From [functions] - [private] - [Gitignore] #region - From [functions] - [private] - [License] Write-Verbose "[$scriptName] - [functions] - [private] - [License] - Processing folder" #region - From [functions] - [private] - [License] - [Get-GitHubLicenseByName] Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseByName] - Importing" filter Get-GitHubLicenseByName { <# .SYNOPSIS Get a license .DESCRIPTION Gets information about a specific license. For more information, see "[Licensing a repository ](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository)." .EXAMPLE Get-GitHubGitignoreList Get all gitignore templates .NOTES https://docs.github.com/rest/licenses/licenses#get-a-license #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding()] param ( # The license keyword, license name, or license SPDX ID. For example, mit or mpl-2.0. [Parameter()] [ValidateNotNullOrEmpty()] [Alias('license')] [string] $Name ) process { $inputObject = @{ APIEndpoint = "/licenses/$Name" Accept = 'application/vnd.github+json' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseByName] - Done" #endregion - From [functions] - [private] - [License] - [Get-GitHubLicenseByName] #region - From [functions] - [private] - [License] - [Get-GitHubLicenseList] Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseList] - Importing" filter Get-GitHubLicenseList { <# .SYNOPSIS Get all commonly used licenses .DESCRIPTION Lists the most commonly used licenses on GitHub. For more information, see "[Licensing a repository ](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository)." .EXAMPLE Get-GitHubLicenseList Get all commonly used licenses. .NOTES https://docs.github.com/rest/licenses/licenses#get-all-commonly-used-licenses #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [OutputType([string[]])] [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/licenses' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseList] - Done" #endregion - From [functions] - [private] - [License] - [Get-GitHubLicenseList] #region - From [functions] - [private] - [License] - [Get-GitHubRepositoryLicense] Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubRepositoryLicense] - Importing" filter Get-GitHubRepositoryLicense { <# .SYNOPSIS Get the license for a repository .DESCRIPTION This method returns the contents of the repository's license file, if one is detected. Similar to [Get repository content](https://docs.github.com/rest/repos/contents#get-repository-content), this method also supports [custom media types](https://docs.github.com/rest/overview/media-types) for retrieving the raw license content or rendered license HTML. .EXAMPLE Get-GitHubRepositoryLicense -Owner 'octocat' -Repo 'Hello-World' Get the license for the Hello-World repository from the octocat account. .NOTES https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/license" Accept = 'application/vnd.github+json' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { $Response = $_.Response $rawContent = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Response.content)) $Response | Add-Member -NotePropertyName 'raw_content' -NotePropertyValue $rawContent -Force $Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubRepositoryLicense] - Done" #endregion - From [functions] - [private] - [License] - [Get-GitHubRepositoryLicense] Write-Verbose "[$scriptName] - [functions] - [private] - [License] - Done" #endregion - From [functions] - [private] - [License] #region - From [functions] - [private] - [Organization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - Processing folder" #region - From [functions] - [private] - [Organization] - [Blocking] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - Processing folder" #region - From [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization] - 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] - [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization] #region - From [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization] - 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 [List users blocked by an organization](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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/blocks" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization] #region - From [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization] - 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] - [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization] #region - From [functions] - [private] - [Organization] - [Blocking] - [Unblock-GitHubUserByOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Unblock-GitHubUserByOrganization] - 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 = "/orgs/$OrganizationName/blocks/$Username" Method = 'DELETE' } try { $null = (Invoke-GitHubAPI @inputObject) return $true } catch { Write-Error $_.Exception.Response throw $_ } } Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Unblock-GitHubUserByOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Blocking] - [Unblock-GitHubUserByOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - Done" #endregion - From [functions] - [private] - [Organization] - [Blocking] #region - From [functions] - [private] - [Organization] - [Get-GitHubAllOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubAllOrganization] - 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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = @{ since = $Since per_page = $PerPage } $inputObject = @{ APIEndpoint = '/organizations' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubAllOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Get-GitHubAllOrganization] #region - From [functions] - [private] - [Organization] - [Get-GitHubMyOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubMyOrganization] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = '/user/orgs' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubMyOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Get-GitHubMyOrganization] #region - From [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName] - 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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName] - Done" #endregion - From [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName] #region - From [functions] - [private] - [Organization] - [Get-GitHubUserOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubUserOrganization] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/users/$Username/orgs" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubUserOrganization] - Done" #endregion - From [functions] - [private] - [Organization] - [Get-GitHubUserOrganization] Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - Done" #endregion - From [functions] - [private] - [Organization] #region - From [functions] - [private] - [Releases] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - Processing folder" #region - From [functions] - [private] - [Releases] - [Assets] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - Processing folder" #region - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID] - Importing" filter Get-GitHubReleaseAssetByID { <# .SYNOPSIS Get a release asset .DESCRIPTION To download the asset's binary content, set the `Accept` header of the request to [`application/octet-stream`](https://docs.github.com/rest/overview/media-types). The API will either redirect the client to the location, or stream it directly if possible. API clients should handle both a `200` or `302` response. .EXAMPLE Get-GitHubReleaseAssetByID -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'. .NOTES https://docs.github.com/rest/releases/assets#get-a-release-asset #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the asset. [Parameter(Mandatory)] [Alias('asset_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID] - Done" #endregion - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID] #region - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByReleaseID] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByReleaseID] - Importing" filter Get-GitHubReleaseAssetByReleaseID { <# .SYNOPSIS List release assets .DESCRIPTION List release assets .EXAMPLE Get-GitHubReleaseAssetByReleaseID -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'. .NOTES https://docs.github.com/rest/releases/assets#list-release-assets #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the release. [Parameter( Mandatory, ParameterSetName = 'ID' )] [Alias('release_id')] [string] $ID, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/$ID/assets" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByReleaseID] - Done" #endregion - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByReleaseID] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - Done" #endregion - From [functions] - [private] - [Releases] - [Assets] #region - From [functions] - [private] - [Releases] - [Releases] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - Processing folder" #region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll] - Importing" filter Get-GitHubReleaseAll { <# .SYNOPSIS List releases .DESCRIPTION This returns a list of releases, which does not include regular Git tags that have not been associated with a release. To get a list of Git tags, use the [Repository Tags API](https://docs.github.com/rest/repos/repos#list-repository-tags). Information about published releases are available to everyone. Only users with push access will receive listings for draft releases. .EXAMPLE Get-GitHubReleaseAll -Owner 'octocat' -Repo 'hello-world' Gets all the releases for the repository 'hello-world' owned by 'octocat'. .NOTES https://docs.github.com/rest/releases/releases#list-releases #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter(ParameterSetName = 'AllUsers')] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll] - Done" #endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll] #region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID] - Importing" filter Get-GitHubReleaseByID { <# .SYNOPSIS Get a release .DESCRIPTION **Note:** This returns an `upload_url` key corresponding to the endpoint for uploading release assets. This key is a [hypermedia resource](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia). .EXAMPLE Get-GitHubReleaseById -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. .NOTES https://docs.github.com/rest/releases/releases#get-a-release #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the release. [Parameter( Mandatory )] [Alias('release_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/$ID" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID] - Done" #endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID] #region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName] - Importing" filter Get-GitHubReleaseByTagName { <# .SYNOPSIS Get a release by tag name .DESCRIPTION Get a published release with the specified tag. .EXAMPLE Get-GitHubReleaseByTagName -Owner 'octocat' -Repo 'hello-world' -Tag 'v1.0.0' Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'. .NOTES https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The name of the tag to get a release from. [Parameter( Mandatory )] [Alias('tag_name')] [string] $Tag ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/tags/$Tag" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName] - Done" #endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName] #region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseLatest] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseLatest] - Importing" filter Get-GitHubReleaseLatest { <# .SYNOPSIS Get the latest release .DESCRIPTION View the latest published full release for the repository. The latest release is the most recent non-prerelease, non-draft release, sorted by the `created_at` attribute. The `created_at` attribute is the date of the commit used for the release, and not the date when the release was drafted or published. .EXAMPLE Get-GitHubReleaseLatest -Owner 'octocat' -Repo 'hello-world' Gets the latest releases for the repository 'hello-world' owned by 'octocat'. .NOTES https://docs.github.com/rest/releases/releases#get-the-latest-release #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/latest" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseLatest] - Done" #endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseLatest] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - Done" #endregion - From [functions] - [private] - [Releases] - [Releases] Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - Done" #endregion - From [functions] - [private] - [Releases] #region - From [functions] - [private] - [Repositories] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - Processing folder" #region - From [functions] - [private] - [Repositories] - [Autolinks] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - Processing folder" #region - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById] - Importing" filter Get-GitHubRepositoryAutolinkById { <# .SYNOPSIS Get an autolink reference of a repository .DESCRIPTION This returns a single autolink reference by ID that was configured for the given repository. Information about autolinks are only available to repository administrators. .EXAMPLE Get-GitHubRepositoryAutolinkById -Owner 'octocat' -Repo 'Hello-World' -ID 1 Gets the autolink with the ID 1 for the repository 'Hello-World' owned by 'octocat'. .NOTES https://docs.github.com/rest/repos/autolinks#get-an-autolink-reference-of-a-repository #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the autolink. [Parameter(Mandatory)] [Alias('autolink_id')] [Alias('ID')] [int] $AutolinkId ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/autolinks/$AutolinkId" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById] - Done" #endregion - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById] #region - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList] - Importing" filter Get-GitHubRepositoryAutolinkList { <# .SYNOPSIS List all autolinks of a repository .DESCRIPTION This returns a list of autolinks configured for the given repository. Information about autolinks are only available to repository administrators. .EXAMPLE Get-GitHubRepositoryAutolinkList -Owner 'octocat' -Repo 'Hello-World' Gets all autolinks for the repository 'Hello-World' owned by 'octocat'. .NOTES https://docs.github.com/rest/repos/autolinks#list-all-autolinks-of-a-repository #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/autolinks" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList] - Done" #endregion - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - Done" #endregion - From [functions] - [private] - [Repositories] - [Autolinks] #region - From [functions] - [private] - [Repositories] - [Fork] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Fork] - Processing folder" #region - From [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork] - Importing" filter New-GitHubRepositoryAsFork { <# .SYNOPSIS Create a fork .DESCRIPTION Create a fork for the authenticated user. **Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Support](https://support.github.com/contact?tags=dotcom-rest-api). **Note**: Although this endpoint works with GitHub Apps, the GitHub App must be installed on the destination account with access to all repositories and on the source account with access to the source repository. .EXAMPLE New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' Fork the repository `Hello-World` owned by `github` for the authenticated user. Repo will be named `Hello-World`, and all branches and tags will be forked. .EXAMPLE New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -Name 'Hello-World-2' Fork the repository `Hello-World` owned by `github` for the authenticated user, naming the resulting repository `Hello-World-2`. .EXAMPLE New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -Organization 'octocat' Fork the repository `Hello-World` owned by `github` for the organization `octocat`, naming the resulting repository `Hello-World`. .EXAMPLE New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -DefaultBranchOnly Fork the repository `Hello-World` owned by `github` for the authenticated user, forking only the default branch. .NOTES https://docs.github.com/rest/repos/forks#create-a-fork #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] [string] $Repo, # The organization or person who will own the new repository. # To create a new repository in an organization, the authenticated user must be a member of the specified organization. [Parameter()] [string] $Organization = (Get-GitHubConfig -Name Owner), # The name of the new repository. [Parameter()] [string] $Name, # When forking from an existing repository, fork with only the default branch. [Parameter()] [Alias('default_branch_only')] [switch] $DefaultBranchOnly ) if ([string]::IsNullorEmpty($Name)) { $Name = $ForkRepo } $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $body['default_branch_only'] = $DefaultBranchOnly $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/forks" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("Repository [$Organization/$Name] as fork of [$Owner/$Repo]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork] - Done" #endregion - From [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Fork] - Done" #endregion - From [functions] - [private] - [Repositories] - [Fork] #region - From [functions] - [private] - [Repositories] - [Repositories] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - Processing folder" #region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories] - Importing" filter Get-GitHubMyRepositories { <# .SYNOPSIS List repositories for the authenticated user .DESCRIPTION Lists repositories that the authenticated user has explicit permission (`:read`, `:write`, or `:admin`) to access. The authenticated user has explicit permission to access repositories they own, repositories where they are a collaborator, and repositories that they can access through an organization membership. .EXAMPLE Get-GitHubMyRepositories Gets the repositories for the authenticated user. .EXAMPLE Get-GitHubMyRepositories -Visibility 'private' Gets the private repositories for the authenticated user. .EXAMPLE $param = @{ Visibility = 'public' Affiliation = 'owner','collaborator' Sort = 'created' Direction = 'asc' PerPage = 100 Since = (Get-Date).AddYears(-5) Before = (Get-Date).AddDays(-1) } Get-GitHubMyRepositories @param Gets the public repositories for the authenticated user that are owned by the authenticated user or that the authenticated user has been added to as a collaborator. The results are sorted by creation date in ascending order and the results are limited to 100 repositories. The results are limited to repositories created between 5 years ago and 1 day ago. .EXAMPLE Get-GitHubMyRepositories -Type 'forks' Gets the forked repositories for the authenticated user. .EXAMPLE Get-GitHubMyRepositories -Type 'sources' Gets the non-forked repositories for the authenticated user. .EXAMPLE Get-GitHubMyRepositories -Type 'member' Gets the repositories for the authenticated user that are owned by an organization. .NOTES https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user #> [CmdletBinding(DefaultParameterSetName = 'Type')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')] param ( # Limit results to repositories with the specified visibility. [Parameter( ParameterSetName = 'Aff-Vis' )] [ValidateSet('all', 'public', 'private')] [string] $Visibility = 'all', # Comma-separated list of values. Can include: # - owner: Repositories that are owned by the authenticated user. # - collaborator: Repositories that the user has been added to as a collaborator. # - organization_member: Repositories that the user has access to through being a member of an organization. # This includes every repository on every team that the user is on. # Default: owner, collaborator, organization_member [Parameter( ParameterSetName = 'Aff-Vis' )] [ValidateSet('owner', 'collaborator', 'organization_member')] [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), # Specifies the types of repositories you want returned. [Parameter( ParameterSetName = 'Type' )] [ValidateSet('all', 'owner', 'public', 'private', 'member')] [string] $Type = 'all', # The property to sort the results by. [Parameter()] [ValidateSet('created', 'updated', 'pushed', 'full_name')] [string] $Sort = 'created', # The order to sort by. # Default: asc when using full_name, otherwise desc. [Parameter()] [ValidateSet('asc', 'desc')] [string] $Direction, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30, # Only show repositories updated after the given time. [Parameter()] [datetime] $Since, # Only show repositories updated before the given time. [Parameter()] [datetime] $Before ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)]" $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)] - Adding default value" $PSBoundParameters[$_.Key] = $paramDefaultValue } Write-Verbose " - $($PSBoundParameters[$_.Key])" } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Affiliation', 'Since', 'Before' if ($PSBoundParameters.ContainsKey('Affiliation')) { $body['affiliation'] = $Affiliation -join ',' } if ($PSBoundParameters.ContainsKey('Since')) { $body['since'] = $Since.ToString('yyyy-MM-ddTHH:mm:ssZ') } if ($PSBoundParameters.ContainsKey('Before')) { $body['before'] = $Before.ToString('yyyy-MM-ddTHH:mm:ssZ') } $inputObject = @{ APIEndpoint = '/user/repos' Method = 'GET' body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories] #region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName] - Importing" filter Get-GitHubRepositoryByName { <# .SYNOPSIS Get a repository .DESCRIPTION The `parent` and `source` objects are present when the repository is a fork. `parent` is the repository this repository was forked from, `source` is the ultimate source for the network. **Note:** In order to see the `security_and_analysis` block for a repository 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](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)." .EXAMPLE Get-GitHubRepositoryByName -Owner 'octocat' -Repo 'Hello-World' Gets the repository 'Hello-World' for the organization 'octocat'. .NOTES https://docs.github.com/rest/repos/repos#get-a-repository #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName] #region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID] - Importing" filter Get-GitHubRepositoryListByID { <# .SYNOPSIS List public repositories .DESCRIPTION Lists all public repositories in the order that they were created. Note: - For GitHub Enterprise Server, this endpoint will only list repositories available to all users on the enterprise. - 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 repositories. .EXAMPLE Get-GitHubRepositoryListByID -Since '123456789 Gets the repositories with an ID equals and greater than 123456789. .NOTES https://docs.github.com/rest/repos/repos#list-public-repositories #> [CmdletBinding()] param ( # A repository ID. Only return repositories with an ID greater than this ID. [Parameter()] [int] $Since = 0 ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)]" $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)] - Adding default value" $PSBoundParameters[$_.Key] = $paramDefaultValue } Write-Verbose " - $($PSBoundParameters[$_.Key])" } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/repositories' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID] #region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg] - Importing" filter Get-GitHubRepositoryListByOrg { <# .SYNOPSIS List organization repositories .DESCRIPTION Lists repositories for the specified organization. **Note:** In order to see the `security_and_analysis` block for a repository 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](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)." .EXAMPLE Get-GitHubRepositoryListByOrg -Owner 'octocat' Gets the repositories for the organization 'octocat'. .EXAMPLE Get-GitHubRepositoryListByOrg -Owner 'octocat' -Type 'public' Gets the public repositories for the organization 'octocat'. .EXAMPLE Get-GitHubRepositoryListByOrg -Owner 'octocat' -Sort 'created' -Direction 'asc' Gets the repositories for the organization 'octocat' sorted by creation date in ascending order. .NOTES https://docs.github.com/rest/repos/repos#list-organization-repositories #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # Specifies the types of repositories you want returned. [Parameter()] [validateSet('all', 'public', 'private', 'forks', 'sources', 'member')] [string] $type = 'all', # The property to sort the results by. [Parameter()] [validateSet('created', 'updated', 'pushed', 'full_name')] [string] $Sort = 'created', # The order to sort by. # Default: asc when using full_name, otherwise desc. [Parameter()] [validateSet('asc', 'desc')] [string] $Direction, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)]" $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)] - Adding default value" $PSBoundParameters[$_.Key] = $paramDefaultValue } Write-Verbose " - $($PSBoundParameters[$_.Key])" } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner' $inputObject = @{ APIEndpoint = "/orgs/$Owner/repos" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg] #region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser] - Importing" filter Get-GitHubRepositoryListByUser { <# .SYNOPSIS List repositories for a user .DESCRIPTION Lists public repositories for the specified user. Note: For GitHub AE, this endpoint will list internal repositories for the specified user. .EXAMPLE Get-GitHubRepositoryListByUser -Username 'octocat' Gets the repositories for the user 'octocat'. .EXAMPLE Get-GitHubRepositoryListByUser -Username 'octocat' -Type 'member' Gets the repositories of organizations where the user 'octocat' is a member. .EXAMPLE Get-GitHubRepositoryListByUser -Username 'octocat' -Sort 'created' -Direction 'asc' Gets the repositories for the user 'octocat' sorted by creation date in ascending order. .NOTES https://docs.github.com/rest/repos/repos#list-repositories-for-a-user #> [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('login')] [string] $Username, # Specifies the types of repositories you want returned. [Parameter()] [validateSet('all', 'owner', 'member')] [string] $Type = 'all', # The property to sort the results by. [Parameter()] [validateSet('created', 'updated', 'pushed', 'full_name')] [string] $Sort = 'created', # The order to sort by. # Default: asc when using full_name, otherwise desc. [Parameter()] [validateSet('asc', 'desc')] [string] $Direction, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)]" $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) { Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)] - Adding default value" $PSBoundParameters[$_.Key] = $paramDefaultValue } Write-Verbose " - $($PSBoundParameters[$_.Key])" } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Username' $inputObject = @{ APIEndpoint = "/users/$Username/repos" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser] #region - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate] - Importing" filter New-GitHubRepositoryFromTemplate { <# .SYNOPSIS Create a repository using a template .DESCRIPTION Creates a new repository using a repository template. Use the `template_owner` and `template_repo` route parameters to specify the repository to use as the template. If the repository is not public, the authenticated user must own or be a member of an organization that owns the repository. To check if a repository is available to use as a template, get the repository's information using the [Get a repository](https://docs.github.com/rest/repos/repos#get-a-repository) endpoint and check that the `is_template` key is `true`. **OAuth scope requirements** When using [OAuth](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/), authorizations must include: * `public_repo` scope or `repo` scope to create a public repository. Note: For GitHub AE, use `repo` scope to create an internal repository. * `repo` scope to create a private repository .EXAMPLE $params = @{ TemplateOwner = 'GitHub' TemplateRepo = 'octocat' Owner = 'PSModule' Name = 'MyNewRepo' IncludeAllBranches = $true Description = 'My new repo' Private = $true } New-GitHubRepositoryFromTemplate @params Creates a new private repository named `MyNewRepo` from the `octocat` template repository owned by `GitHub`. .NOTES https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the template repository. The name is not case sensitive. [Parameter(Mandatory)] [Alias('template_owner')] [string] $TemplateOwner, # The name of the template repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] [Alias('template_repo')] [string] $TemplateRepo, # The organization or person who will own the new repository. # To create a new repository in an organization, the authenticated user must be a member of the specified organization. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the new repository. [Parameter(Mandatory)] [string] $Name, # A short description of the new repository. [Parameter()] [string] $Description, # Set to true to include the directory structure and files from all branches in the template repository, # and not just the default branch. [Parameter()] [Alias('include_all_branches')] [switch] $IncludeAllBranches, # Either true to create a new private repository or false to create a new public one. [Parameter()] [switch] $Private ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'TemplateOwner', 'TemplateRepo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$TemplateOwner/$TemplateRepo/generate" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Name] from template [$TemplateOwner/$TemplateRepo]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate] #region - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg] - Importing" #Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } filter New-GitHubRepositoryOrg { <# .SYNOPSIS Create an organization repository .DESCRIPTION Creates a new repository in the specified organization. The authenticated user must be a member of the organization. **OAuth scope requirements** When using [OAuth](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/), authorizations must include: * `public_repo` scope or `repo` scope to create a public repository. Note: For GitHub AE, use `repo` scope to create an internal repository. * `repo` scope to create a private repository .EXAMPLE $params = @{ Owner = 'PSModule' Name = 'Hello-World' Description = 'This is your first repository' Homepage = 'https://github.com' HasIssues = $true HasProjects = $true HasWiki = $true HasDownloads = $true IsTemplate = $true AutoInit = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true SquashMergeCommitTitle = 'PR_TITLE' SquashMergeCommitMessage = 'PR_BODY' } New-GitHubRepositoryOrg @params Creates a new public repository named "Hello-World" owned by the organization "PSModule". .PARAMETER GitignoreTemplate Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell". .PARAMETER LicenseTemplate Choose an open source license template that best suits your needs, and then use the license keyword as the license_template string. For example, "mit" or "mpl-2.0". .NOTES https://docs.github.com/rest/repos/repos#create-an-organization-repository #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseDeclaredVarsMoreThanAssignments', 'GitignoreTemplate', Justification = 'Parameter is used in dynamic parameter validation.' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseDeclaredVarsMoreThanAssignments', 'LicenseTemplate', Justification = 'Parameter is used in dynamic parameter validation.' )] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository. [Parameter(Mandatory)] [string] $Name, # A short description of the repository. [Parameter()] [string] $Description, # A URL with more information about the repository. [Parameter()] [ValidateNotNullOrEmpty()] [uri] $Homepage, # The visibility of the repository. [Parameter()] [ValidateSet('public', 'private')] [string] $Visibility = 'public', # Either true to enable issues for this repository or false to disable them. [Parameter()] [Alias('has_issues')] [switch] $HasIssues, # Either true to enable projects for this repository or false to disable them. # Note: If you're creating a repository in an organization that has disabled repository projects, the default is false, # and if you pass true, the API returns an error. [Parameter()] [Alias('has_projects')] [switch] $HasProjects, # Either true to enable the wiki for this repository or false to disable it. [Parameter()] [Alias('has_wiki')] [switch] $HasWiki, # Whether downloads are enabled. [Parameter()] [Alias('has_downloads')] [switch] $HasDownloads, # Either true to make this repo available as a template repository or false to prevent it. [Parameter()] [Alias('is_template')] [switch] $IsTemplate, # The ID of the team that will be granted access to this repository. This is only valid when creating a repository in an organization. [Parameter()] [Alias('team_id')] [int] $TeamId, # Pass true to create an initial commit with empty README. [Parameter()] [Alias('auto_init')] [switch] $AutoInit, # Either true to allow squash-merging pull requests, or false to prevent squash-merging. [Parameter()] [Alias('allow_squash_merge')] [switch] $AllowSquashMerge, # Either true to allow merging pull requests with a merge commit, or false to prevent merging pull requests with merge commits. [Parameter()] [Alias('allow_merge_commit')] [switch] $AllowMergeCommit, # Either true to allow rebase-merging pull requests, or false to prevent rebase-merging. [Parameter()] [Alias('allow_rebase_merge')] [switch] $AllowRebaseMerge, # Either true to allow auto-merge on pull requests, or false to disallow auto-merge. [Parameter()] [Alias('allow_auto_merge')] [switch] $AllowAutoMerge, # Either true to allow automatically deleting head branches when pull requests are merged, or false to prevent automatic deletion. # The authenticated user must be an organization owner to set this property to true. [Parameter()] [Alias('delete_branch_on_merge')] [switch] $DeleteBranchOnMerge, # The default value for a squash merge commit title: # - PR_TITLE - default to the pull request's title. # - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit). [Parameter()] [ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')] [Alias('squash_merge_commit_title')] [string] $SquashMergeCommitTitle, # The default value for a squash merge commit message: # - PR_BODY - default to the pull request's body. # - COMMIT_MESSAGES - default to the branch's commit messages. # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')] [Alias('squash_merge_commit_message')] [string] $SquashMergeCommitMessage, # The default value for a merge commit title. # - PR_TITLE - default to the pull request's title. # - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name). [Parameter()] [ValidateSet('PR_TITLE', 'MERGE_MESSAGE')] [Alias('merge_commit_title')] [string] $MergeCommitTitle, # The default value for a merge commit message. # - PR_BODY - default to the pull request's body. # - PR_TITLE - default to the pull request's title. # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')] [Alias('merge_commit_message')] [string] $MergeCommitMessage ) dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ Name = 'GitignoreTemplate' Alias = 'gitignore_template' Type = [string] ValidateSet = Get-GitHubGitignoreList DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam $dynParam2 = @{ Name = 'LicenseTemplate' Alias = 'license_template' Type = [string] ValidateSet = Get-GitHubLicenseList | Select-Object -ExpandProperty key DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam2 return $DynamicParamDictionary } begin { $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate'] $LicenseTemplate = $PSBoundParameters['LicenseTemplate'] } process { $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner' -RemoveTypes 'SwitchParameter' $body['private'] = $Visibility -eq 'private' $body['has_issues'] = if ($HasIssues.IsPresent) { $HasIssues } else { $false } $body['has_wiki'] = if ($HasWiki.IsPresent) { $HasWiki } else { $false } $body['has_projects'] = if ($HasProjects.IsPresent) { $HasProjects } else { $false } $body['has_downloads'] = if ($HasDownloads.IsPresent) { $HasDownloads } else { $false } $body['is_template'] = if ($IsTemplate.IsPresent) { $IsTemplate } else { $false } $body['auto_init'] = if ($AutoInit.IsPresent) { $AutoInit } else { $false } $body['allow_squash_merge'] = if ($AllowSquashMerge.IsPresent) { $AllowSquashMerge } else { $false } $body['allow_merge_commit'] = if ($AllowMergeCommit.IsPresent) { $AllowMergeCommit } else { $false } $body['allow_rebase_merge'] = if ($AllowRebaseMerge.IsPresent) { $AllowRebaseMerge } else { $false } $body['allow_auto_merge'] = if ($AllowAutoMerge.IsPresent) { $AllowAutoMerge } else { $false } $body['delete_branch_on_merge'] = if ($DeleteBranchOnMerge.IsPresent) { $DeleteBranchOnMerge } else { $false } Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues $inputObject = @{ APIEndpoint = "/orgs/$Owner/repos" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("Repository in organization $Owner", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg] #region - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser] - Importing" #Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } filter New-GitHubRepositoryUser { <# .SYNOPSIS Create a repository for the authenticated user .DESCRIPTION Creates a new repository for the authenticated user. **OAuth scope requirements** When using [OAuth](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/), authorizations must include: * `public_repo` scope or `repo` scope to create a public repository. Note: For GitHub AE, use `repo` scope to create an internal repository. * `repo` scope to create a private repository. .EXAMPLE $params = @{ Name = 'Hello-World' Description = 'This is your first repository' Homepage = 'https://github.com' HasIssues = $true HasProjects = $true HasWiki = $true HasDownloads = $true IsTemplate = $true AutoInit = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true SquashMergeCommitTitle = 'PR_TITLE' SquashMergeCommitMessage = 'PR_BODY' } New-GitHubRepositoryUser @params Creates a new public repository named "Hello-World" owned by the authenticated user. .PARAMETER GitignoreTemplate The desired language or platform to apply to the .gitignore. .PARAMETER LicenseTemplate The license keyword of the open source license for this repository. .NOTES https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseDeclaredVarsMoreThanAssignments', 'GitignoreTemplate', Justification = 'Parameter is used in dynamic parameter validation.' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseDeclaredVarsMoreThanAssignments', 'LicenseTemplate', Justification = 'Parameter is used in dynamic parameter validation.' )] [CmdletBinding(SupportsShouldProcess)] param ( # The name of the repository. [Parameter(Mandatory)] [string] $Name, # A short description of the repository. [Parameter()] [string] $Description, # A URL with more information about the repository. [Parameter()] [ValidateNotNullOrEmpty()] [uri] $Homepage, # The visibility of the repository. [Parameter()] [ValidateSet('public', 'private')] [string] $Visibility = 'public', # Whether issues are enabled. [Parameter()] [Alias('has_issues')] [switch] $HasIssues, # Whether projects are enabled. [Parameter()] [Alias('has_projects')] [switch] $HasProjects, # Whether the wiki is enabled. [Parameter()] [Alias('has_wiki')] [switch] $HasWiki, # Whether discussions are enabled. [Parameter()] [Alias('has_discussions')] [switch] $HasDiscussions, # Whether downloads are enabled. [Parameter()] [Alias('has_downloads')] [switch] $HasDownloads, # Whether this repository acts as a template that can be used to generate new repositories. [Parameter()] [Alias('is_template')] [switch] $IsTemplate, # The ID of the team that will be granted access to this repository. This is only valid when creating a repository in an organization. [Parameter()] [Alias('team_id')] [int] $TeamId, # Pass true to create an initial commit with empty README. [Parameter()] [Alias('auto_init')] [switch] $AutoInit, # Whether to allow squash merges for pull requests. [Parameter()] [Alias('allow_squash_merge')] [switch] $AllowSquashMerge, # Whether to allow merge commits for pull requests. [Parameter()] [Alias('allow_merge_commit')] [switch] $AllowMergeCommit, # Whether to allow rebase merges for pull requests. [Parameter()] [Alias('allow_rebase_merge')] [switch] $AllowRebaseMerge, # Whether to allow Auto-merge to be used on pull requests. [Parameter()] [Alias('allow_auto_merge')] [switch] $AllowAutoMerge, # Whether to delete head branches when pull requests are merged [Parameter()] [Alias('delete_branch_on_merge')] [switch] $DeleteBranchOnMerge, # The default value for a squash merge commit title: # - PR_TITLE - default to the pull request's title. # - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit). [Parameter()] [ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')] [Alias('squash_merge_commit_title')] [string] $SquashMergeCommitTitle, # The default value for a squash merge commit message: # - PR_BODY - default to the pull request's body. # - COMMIT_MESSAGES - default to the branch's commit messages. # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')] [Alias('squash_merge_commit_message')] [string] $SquashMergeCommitMessage, # The default value for a merge commit title. # - PR_TITLE - default to the pull request's title. # - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name). [Parameter()] [ValidateSet('PR_TITLE', 'MERGE_MESSAGE')] [Alias('merge_commit_title')] [string] $MergeCommitTitle, # The default value for a merge commit message. # - PR_BODY - default to the pull request's body. # - PR_TITLE - default to the pull request's title. # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')] [Alias('merge_commit_message')] [string] $MergeCommitMessage ) dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ Name = 'GitignoreTemplate' Alias = 'gitignore_template' Type = [string] ValidateSet = Get-GitHubGitignoreList DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam $dynParam2 = @{ Name = 'LicenseTemplate' Alias = 'license_template' Type = [string] ValidateSet = Get-GitHubLicenseList | Select-Object -ExpandProperty key DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam2 return $DynamicParamDictionary } begin { $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate'] $LicenseTemplate = $PSBoundParameters['LicenseTemplate'] } process { $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'visibility' -RemoveTypes 'SwitchParameter' $body['private'] = $Visibility -eq 'private' $body['has_issues'] = if ($HasIssues.IsPresent) { $HasIssues } else { $false } $body['has_wiki'] = if ($HasWiki.IsPresent) { $HasWiki } else { $false } $body['has_projects'] = if ($HasProjects.IsPresent) { $HasProjects } else { $false } $body['has_downloads'] = if ($HasDownloads.IsPresent) { $HasDownloads } else { $false } $body['is_template'] = if ($IsTemplate.IsPresent) { $IsTemplate } else { $false } $body['auto_init'] = if ($AutoInit.IsPresent) { $AutoInit } else { $false } $body['allow_squash_merge'] = if ($AllowSquashMerge.IsPresent) { $AllowSquashMerge } else { $false } $body['allow_merge_commit'] = if ($AllowMergeCommit.IsPresent) { $AllowMergeCommit } else { $false } $body['allow_rebase_merge'] = if ($AllowRebaseMerge.IsPresent) { $AllowRebaseMerge } else { $false } $body['allow_auto_merge'] = if ($AllowAutoMerge.IsPresent) { $AllowAutoMerge } else { $false } $body['delete_branch_on_merge'] = if ($DeleteBranchOnMerge.IsPresent) { $DeleteBranchOnMerge } else { $false } Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues $inputObject = @{ APIEndpoint = '/user/repos' Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess('Repository for user', 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } } Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - Done" #endregion - From [functions] - [private] - [Repositories] - [Repositories] Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - Done" #endregion - From [functions] - [private] - [Repositories] #region - From [functions] - [private] - [Users] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - Processing folder" #region - From [functions] - [private] - [Users] - [Blocking] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - Processing folder" #region - From [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser] - 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] - [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser] - Done" #endregion - From [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser] #region - From [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser] - 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 [List users blocked by the authenticated user](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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/blocks' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser] - Done" #endregion - From [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser] #region - From [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser] - 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()] [ValidateRange(1, 100)] [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] - [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser] - Done" #endregion - From [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser] #region - From [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser] - 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] - [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser] - Done" #endregion - From [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - Done" #endregion - From [functions] - [private] - [Users] - [Blocking] #region - From [functions] - [private] - [Users] - [Emails] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - Processing folder" #region - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/emails' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail] - Done" #endregion - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail] #region - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserPublicEmail] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserPublicEmail] - 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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Link to documentation.')] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/public_emails' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserPublicEmail] - Done" #endregion - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserPublicEmail] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - Done" #endregion - From [functions] - [private] - [Users] - [Emails] #region - From [functions] - [private] - [Users] - [Followers] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - Processing folder" #region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/followers" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser] #region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/following' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe] #region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/following" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser] #region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers] - 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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/followers' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers] #region - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe] - 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] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe] #region - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser] - 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] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - Done" #endregion - From [functions] - [private] - [Users] - [Followers] #region - From [functions] - [private] - [Users] - [GPG-Keys] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - Processing folder" #region - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/gpg_keys" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser] - Done" #endregion - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser] #region - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/gpg_keys' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey] - Done" #endregion - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey] #region - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKeyById] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKeyById] - 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 -ID '1234567' Gets the GPG key with ID '1234567' 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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKeyById] - Done" #endregion - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKeyById] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - Done" #endregion - From [functions] - [private] - [Users] - [GPG-Keys] #region - From [functions] - [private] - [Users] - [Keys] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - Processing folder" #region - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser] - Importing" filter Get-GitHubUserKeyForUser { <# .SYNOPSIS List public SSH keys for a user .DESCRIPTION Lists the _verified_ public SSH keys for a user. This is accessible by anyone. .EXAMPLE Get-GitHubUserKeyForUser -Username 'octocat' Gets all public SSH keys for the 'octocat' user. .NOTES https://docs.github.com/rest/users/keys#list-public-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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/keys" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser] - Done" #endregion - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser] #region - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey] - Importing" filter Get-GitHubUserMyKey { <# .SYNOPSIS List public SSH keys for the authenticated user .DESCRIPTION Lists the public SSH keys for the authenticated user's GitHub account. Requires that you are authenticated via Basic Auth or via OAuth with at least `read:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Get-GitHubUserMyKey Gets all public SSH keys for the authenticated user. .NOTES https://docs.github.com/rest/users/keys#list-public-ssh-keys-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/keys' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey] - Done" #endregion - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey] #region - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKeyById] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKeyById] - Importing" filter Get-GitHubUserMyKeyById { <# .SYNOPSIS Get a public SSH key for the authenticated user .DESCRIPTION View extended details for a single public SSH key. Requires that you are authenticated via Basic Auth or via OAuth with at least `read:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Get-GitHubUserMyKeyById -ID '1234567' Gets the public SSH key with the ID '1234567' for the authenticated user. .NOTES https://docs.github.com/rest/users/keys#get-a-public-ssh-key-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The unique identifier of the key. [Parameter( Mandatory )] [Alias('key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/keys/$ID" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKeyById] - Done" #endregion - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKeyById] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - Done" #endregion - From [functions] - [private] - [Users] - [Keys] #region - From [functions] - [private] - [Users] - [Social-Accounts] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - Processing folder" #region - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials] - 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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/social_accounts' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials] - Done" #endregion - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials] #region - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubUserSocialsByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubUserSocialsByName] - 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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubUserSocialsByName] - Done" #endregion - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubUserSocialsByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - Done" #endregion - From [functions] - [private] - [Users] - [Social-Accounts] #region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - Processing folder" #region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey] - Importing" filter Get-GitHubUserMySigningKey { <# .SYNOPSIS List SSH signing keys for the authenticated user .DESCRIPTION Lists the SSH signing keys for the authenticated user's GitHub account. You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `read:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)." .EXAMPLE Get-GitHubUserMySigningKey Lists the SSH signing keys for the authenticated user's GitHub account. .NOTES https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/ssh_signing_keys' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey] - Done" #endregion - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey] #region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById] - Importing" filter Get-GitHubUserMySigningKeyById { <# .SYNOPSIS Get an SSH signing key for the authenticated user .DESCRIPTION Gets extended details for an SSH signing key. You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `read:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)." .EXAMPLE Get-GitHubUserMySigningKeyById -ID '1234567' Gets the SSH signing key with the ID '1234567' for the authenticated user. .NOTES https://docs.github.com/rest/users/ssh-signing-keys#get-an-ssh-signing-key-for-the-authenticated-user #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The unique identifier of the SSH signing key. [Parameter( Mandatory )] [Alias('ssh_signing_key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/ssh_signing_keys/$ID" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById] - Done" #endregion - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById] #region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKeyForUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKeyForUser] - Importing" filter Get-GitHubUserSigningKeyForUser { <# .SYNOPSIS List SSH signing keys for a user .DESCRIPTION List SSH signing keys for a user .EXAMPLE Get-GitHubUserSigningKeyForUser -Username 'octocat' Gets the SSH signing keys for the user 'octocat'. .NOTES https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'username' $inputObject = @{ APIEndpoint = "/users/$Username/ssh_signing_keys" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKeyForUser] - Done" #endregion - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKeyForUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - Done" #endregion - From [functions] - [private] - [Users] - [SSH-Signing-Keys] #region - From [functions] - [private] - [Users] - [Get-GitHubAllUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubAllUser] - 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/users' Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubAllUser] - Done" #endregion - From [functions] - [private] - [Users] - [Get-GitHubAllUser] #region - From [functions] - [private] - [Users] - [Get-GitHubMyUser] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubMyUser] - 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])] [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/user' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubMyUser] - Done" #endregion - From [functions] - [private] - [Users] - [Get-GitHubMyUser] #region - From [functions] - [private] - [Users] - [Get-GitHubUserByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubUserByName] - 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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubUserByName] - Done" #endregion - From [functions] - [private] - [Users] - [Get-GitHubUserByName] Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - Done" #endregion - From [functions] - [private] - [Users] #region - From [functions] - [private] - [Utilities] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - Processing folder" #region - From [functions] - [private] - [Utilities] - [Casing] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - Processing folder" #region - From [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle] - 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] - [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle] - Done" #endregion - From [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle] #region - From [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle] - 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] - [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle] - Done" #endregion - From [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle] #region - From [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle] - 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] - [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle] - Done" #endregion - From [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - Done" #endregion - From [functions] - [private] - [Utilities] - [Casing] #region - From [functions] - [private] - [Utilities] - [Hashtable] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - Processing folder" #region - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable] - 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 )] [AllowNull()] [object] $InputObject ) $InputObject | ConvertTo-Json -Depth 100 | ConvertFrom-Json } Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable] - Done" #endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable] #region - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable] - 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 = if ($NameCasingStyle) { ($item.Name | Convert-StringCasingStyle -To $NameCasingStyle) } else { $item.Name } $hashtable[$name] = $item.Value } $hashtable } Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable] - Done" #endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable] #region - From [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object] - 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] - [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object] - Done" #endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object] #region - From [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry] - Importing" filter Remove-HashtableEntry { <# .SYNOPSIS Remove entries from a hashtable. .DESCRIPTION Remove different types of entries from a hashtable. .EXAMPLE $Hashtable = @{ 'Key1' = 'Value1' 'Key2' = 'Value2' 'Key3' = $null 'Key4' = 'Value4' 'Key5' = '' } $Hashtable | Remove-HashtableEntry -NullOrEmptyValues Remove keys with null or empty values #> [OutputType([void])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Function does not change state.' )] [CmdletBinding()] param ( # The hashtable to remove entries from. [Parameter( Mandatory, ValueFromPipeline )] [hashtable] $Hashtable, # Remove keys with null or empty values. [Parameter()] [switch] $NullOrEmptyValues, # Remove keys of type. [Parameter()] [string[]] $RemoveTypes, # Remove keys with a given name. [Parameter()] [string[]] $RemoveNames, # Remove keys NOT of type. [Parameter()] [string[]] $KeepTypes, # Remove keys NOT with a given name. [Parameter()] [string[]] $KeepNames ) if ($NullOrEmptyValues) { Write-Verbose 'Remove keys with null or empty values' ($Hashtable.GetEnumerator() | Where-Object { [string]::IsNullOrEmpty($_.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] - [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry] - Done" #endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - Done" #endregion - From [functions] - [private] - [Utilities] - [Hashtable] #region - From [functions] - [private] - [Utilities] - [Web] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Web] - Processing folder" #region - From [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString] - 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] - [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString] - Done" #endregion - From [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Web] - Done" #endregion - From [functions] - [private] - [Utilities] - [Web] Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - Done" #endregion - From [functions] - [private] - [Utilities] Write-Verbose "[$scriptName] - [functions] - [private] - Done" #endregion - From [functions] - [private] #region - From [functions] - [public] Write-Verbose "[$scriptName] - [functions] - [public] - Processing folder" #region - From [functions] - [public] - [Actions] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - Processing folder" #region - From [functions] - [public] - [Actions] - [Disable-GitHubWorkflow] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Disable-GitHubWorkflow] - Importing" filter Disable-GitHubWorkflow { <# .NOTES [Disable a workflow](https://docs.github.com/en/rest/actions/workflows#disable-a-workflow) #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string[]] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/disable" Method = 'PUT' } $null = Invoke-GitHubAPI @inputObject } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Disable-GitHubWorkflow] - Done" #endregion - From [functions] - [public] - [Actions] - [Disable-GitHubWorkflow] #region - From [functions] - [public] - [Actions] - [Enable-GitHubWorkflow] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Enable-GitHubWorkflow] - Importing" filter Enable-GitHubWorkflow { <# .NOTES [Enable a workflow](https://docs.github.com/en/rest/actions/workflows#enable-a-workflow) #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string[]] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/enable" Method = 'PUT' } $null = Invoke-GitHubAPI @inputObject } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Enable-GitHubWorkflow] - Done" #endregion - From [functions] - [public] - [Actions] - [Enable-GitHubWorkflow] #region - From [functions] - [public] - [Actions] - [Get-GitHubWorkflow] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflow] - 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 [List repository workflows](https://docs.github.com/rest/actions/workflows?apiVersion=2022-11-28#list-repository-workflows) #> [CmdletBinding(DefaultParameterSetName = 'ByName')] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response.workflows } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflow] - Done" #endregion - From [functions] - [public] - [Actions] - [Get-GitHubWorkflow] #region - From [functions] - [public] - [Actions] - [Get-GitHubWorkflowRun] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflowRun] - Importing" filter Get-GitHubWorkflowRun { <# .NOTES [List workflow runs for a workflow](https://docs.github.com/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-workflow) [List workflow runs for a repository](https://docs.github.com/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository) #> [CmdletBinding(DefaultParameterSetName = 'Repo')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), [Parameter(ParameterSetName = 'ByName')] [string] $Name, [Parameter(ParameterSetName = 'ByID')] [string] $ID, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [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 | ForEach-Object { Write-Output $_.Response.workflow_runs } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflowRun] - Done" #endregion - From [functions] - [public] - [Actions] - [Get-GitHubWorkflowRun] #region - From [functions] - [public] - [Actions] - [Get-GitHubWorkflowUsage] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflowUsage] - 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 [Get workflow usage](https://docs.github.com/en/rest/actions/workflows#get-workflow-usage) #> [CmdletBinding( DefaultParameterSetName = 'ByName' )] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string[]] $ID ) $inputObject = @{ Method = 'GET' APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/timing" } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response.billable } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflowUsage] - Done" #endregion - From [functions] - [public] - [Actions] - [Get-GitHubWorkflowUsage] #region - From [functions] - [public] - [Actions] - [Remove-GitHubWorkflowRun] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Remove-GitHubWorkflowRun] - Importing" filter Remove-GitHubWorkflowRun { <# .SYNOPSIS Delete a workflow run .DESCRIPTION Delete a specific workflow run. Anyone with write 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:write` permission to use this endpoint. .EXAMPLE Remove-GitHubWorkflowRun -Owner 'octocat' -Repo 'Hello-World' -ID 123456789 Deletes the workflow run with the ID 123456789 from the 'Hello-World' repository owned by 'octocat' .NOTES [Delete a workflow run](https://docs.github.com/rest/actions/workflow-runs#delete-a-workflow-run) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the workflow run. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [Alias('ID', 'run_id')] [string] $RunID ) $inputObject = @{ APIEndpoint = "repos/$Owner/$Repo/actions/runs/$RunID" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("workflow run with ID [$RunID] in [$Owner/$Repo]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Remove-GitHubWorkflowRun] - Done" #endregion - From [functions] - [public] - [Actions] - [Remove-GitHubWorkflowRun] #region - From [functions] - [public] - [Actions] - [Start-GitHubWorkflow] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Start-GitHubWorkflow] - 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 [Create a workflow dispatch event](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The ID of the workflow. [Alias('workflow_id')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID, # The reference of the workflow run. The reference can be a branch, tag, or a commit SHA. [Parameter( ValueFromPipelineByPropertyName )] [Alias('branch', 'tag')] [string] $Ref = 'main', # Input parameters for the workflow run. You can use the inputs and payload keys to pass custom data to your workflow. [Parameter()] [hashtable] $Inputs = @{} ) $body = @{ ref = $Ref inputs = $Inputs } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/dispatches" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("workflow with ID [$ID] in [$Owner/$Repo]", 'Start')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Start-GitHubWorkflow] - Done" #endregion - From [functions] - [public] - [Actions] - [Start-GitHubWorkflow] #region - From [functions] - [public] - [Actions] - [Start-GitHubWorkflowReRun] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Start-GitHubWorkflowReRun] - Importing" filter Start-GitHubWorkflowReRun { <# .SYNOPSIS Re-run a workflow .DESCRIPTION Re-runs your workflow run using its `run_id`. You can also specify a branch or tag name to re-run a workflow run from a branch .EXAMPLE Start-GitHubWorkflowReRun -Owner 'octocat' -Repo 'Hello-World' -ID 123456789 .NOTES [Re-run a workflow](https://docs.github.com/en/rest/actions/workflow-runs#re-run-a-workflow) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the workflow run. [Alias('workflow_id')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID ) $inputObject = @{ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repo/actions/runs/$ID/rerun" } if ($PSCmdlet.ShouldProcess("workflow with ID [$ID] in [$Owner/$Repo]", 'Re-run')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Start-GitHubWorkflowReRun] - Done" #endregion - From [functions] - [public] - [Actions] - [Start-GitHubWorkflowReRun] #region - From [functions] - [public] - [Actions] - [Stop-GitHubWorkflowRun] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Stop-GitHubWorkflowRun] - Importing" filter Stop-GitHubWorkflowRun { <# .SYNOPSIS Cancel a workflow run .DESCRIPTION Cancels a workflow run using its `run_id`. You can use this endpoint to cancel a workflow run that is in progress or waiting .EXAMPLE Stop-GitHubWorkflowRun -Owner 'octocat' -Repo 'Hello-World' -ID 123456789 Cancels the workflow run with the ID 123456789 from the 'Hello-World' repository owned by 'octocat' .NOTES [Cancel a workflow run](https://docs.github.com/en/rest/actions/workflow-runs#cancel-a-workflow-run) #> [CmdletBinding(SupportsShouldProcess)] [alias('Cancel-GitHubWorkflowRun')] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), [Alias('workflow_id')] [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $ID ) $inputObject = @{ Method = 'POST' APIEndpoint = "/repos/$Owner/$Repo/actions/runs/$ID/cancel" } if ($PSCmdlet.ShouldProcess("workflow run with ID [$ID] in [$Owner/$Repo]", 'Cancel/Stop')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Stop-GitHubWorkflowRun] - Done" #endregion - From [functions] - [public] - [Actions] - [Stop-GitHubWorkflowRun] Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - Done" #endregion - From [functions] - [public] - [Actions] #region - From [functions] - [public] - [API] Write-Verbose "[$scriptName] - [functions] - [public] - [API] - Processing folder" #region - From [functions] - [public] - [API] - [Invoke-GitHubAPI] Write-Verbose "[$scriptName] - [functions] - [public] - [API] - [Invoke-GitHubAPI] - 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(DefaultParameterSetName = 'ApiEndpoint')] 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( ParameterSetName = 'ApiEndpoint' )] [string] $ApiBaseUri, # The specific endpoint for the API call, e.g., '/repos/user/repo/pulls'. [Parameter( Mandatory, ParameterSetName = 'ApiEndpoint' )] [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 file path to be used for the API request. This is used for uploading files. [Parameter()] [string] $UploadFilePath, # The file path to be used for the API response. This is used for downloading files. [Parameter()] [string] $DownloadFilePath, # The full URI for the API request. This is used for custom API calls. [Parameter( Mandatory, ParameterSetName = 'Uri' )] [string] $URI, # 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] $Token, # 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] $ApiVersion, # The context to use for the API call. This is used to retrieve the necessary configuration settings. [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) Write-Verbose 'Invoking GitHub API...' $PSBoundParameters.GetEnumerator() | ForEach-Object { Write-Verbose " - $($_.Key): $($_.Value)" } $contextObj = Get-GitHubContext -Name $Context Write-Verbose "Using GitHub context: $Context" if (-not $contextObj) { throw 'Log in using Connect-GitHub before running this command.' } if ([string]::IsNullOrEmpty($ApiBaseUri)) { Write-Verbose 'Using default API base URI from context.' Write-Verbose $($contextObj.ApiBaseUri) $ApiBaseUri = $contextObj.ApiBaseUri } Write-Verbose "ApiBaseUri: $ApiBaseUri" if ([string]::IsNullOrEmpty($ApiVersion)) { Write-Verbose 'Using default API version from context.' Write-Verbose $($contextObj.ApiVersion) $ApiVersion = $contextObj.ApiVersion } Write-Verbose "ApiVersion: $ApiVersion" if ([string]::IsNullOrEmpty($TokenType)) { Write-Verbose 'Using default token type from context.' Write-Verbose $($contextObj.TokenType) $TokenType = $contextObj.TokenType } Write-Verbose "TokenType: $TokenType" if ([string]::IsNullOrEmpty($Token)) { Write-Verbose 'Using default token from context.' Write-Verbose $($contextObj.Token) $Token = $contextObj.Token } Write-Verbose "Token: $Token" switch ($tokenType) { 'ghu' { if (Test-GitHubAccessTokenRefreshRequired -Context $Context) { Connect-GitHubAccount -Silent $Token = (Get-GitHubContextSetting -Name 'Token' -Context $Context) } } 'PEM' { $ClientID = (Get-GitHubContextSetting -Name 'ClientID' -Context $Context) $JWT = Get-GitHubAppJSONWebToken -ClientId $ClientID -PrivateKey $Token $Token = $JWT.Token } } $headers = @{ Accept = $Accept 'X-GitHub-Api-Version' = $ApiVersion } Remove-HashtableEntry -Hashtable $headers -NullOrEmptyValues if (-not $URI) { $URI = ("$ApiBaseUri/" -replace '/$', '') + ("/$ApiEndpoint" -replace '^/', '') } $APICall = @{ Uri = $URI Method = $Method Headers = $Headers Authentication = 'Bearer' Token = $Token ContentType = $ContentType FollowRelLink = $FollowRelLink StatusCodeVariable = 'APICallStatusCode' ResponseHeadersVariable = 'APICallResponseHeaders' InFile = $UploadFilePath OutFile = $DownloadFilePath } #If PSversion is higher than 7.1 use HttpVersion if ($PSVersionTable.PSVersion -ge [version]'7.3') { $APICall['HttpVersion'] = $HttpVersion } $APICall | Remove-HashtableEntry -NullOrEmptyValues if ($Body) { # Use body to create the query string for certain situations if ($Method -eq 'GET') { $queryString = $Body | ConvertTo-QueryString $APICall.Uri = $APICall.Uri + $queryString } elseif ($Body -is [string]) { # Use body to create the form data $APICall.Body = $Body } else { $APICall.Body = $Body | ConvertTo-Json -Depth 100 } } try { Write-Verbose 'Calling GitHub API with the following parameters:' Write-Verbose ($APICall | ConvertFrom-HashTable | Format-List | Out-String) Invoke-RestMethod @APICall | ForEach-Object { $statusCode = $APICallStatusCode | ConvertTo-Json -Depth 100 | ConvertFrom-Json $responseHeaders = $APICallResponseHeaders | ConvertTo-Json -Depth 100 | ConvertFrom-Json $verboseMessage = @" ---------------------------------- StatusCode: $statusCode ---------------------------------- Request: $($APICall | ConvertFrom-HashTable | Format-List | Out-String) ---------------------------------- ResponseHeaders: $($responseHeaders.PSObject.Properties | ForEach-Object { $_ | Format-List | Out-String }) ---------------------------------- "@ Write-Verbose $verboseMessage [pscustomobject]@{ Request = $APICall Response = $_ StatusCode = $statusCode ResponseHeaders = $responseHeaders } } } catch { $failure = $_ $errorResult = @" ----------------------------------`n`r Request: $($APICall | ConvertFrom-HashTable | Format-List | Out-String) ----------------------------------`n`r Message: $($failure.Exception.Message | ConvertFrom-HashTable | Format-List | Out-String) ----------------------------------`n`r Response: $($failure.Exception.Response | ConvertFrom-HashTable | Format-List | Out-String) ----------------------------------`n`r "@ Write-Error $errorResult throw $failure.Exception.Message } } Write-Verbose "[$scriptName] - [functions] - [public] - [API] - [Invoke-GitHubAPI] - Done" #endregion - From [functions] - [public] - [API] - [Invoke-GitHubAPI] Write-Verbose "[$scriptName] - [functions] - [public] - [API] - Done" #endregion - From [functions] - [public] - [API] #region - From [functions] - [public] - [Apps] Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - Processing folder" #region - From [functions] - [public] - [Apps] - [Get-GitHubApp] Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubApp] - Importing" filter Get-GitHubApp { <# .SYNOPSIS Get the authenticated app .DESCRIPTION Returns the GitHub App associated with the authentication credentials used. To see how many app installations are associated with this GitHub App, see the `installations_count` in the response. For more details about your app's installations, see the "[List installations for the authenticated app](https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app)" endpoint. You must use a [JWT](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app) to access this endpoint. .EXAMPLE Get-GitHubApp Get the authenticated app. .NOTES [Get the authenticated app | GitHub Docs](https://docs.github.com/rest/apps/apps#get-the-authenticated-app) #> [OutputType([pscustomobject])] [CmdletBinding()] param( # The context to run the command in. [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $inputObject = @{ Context = $Context APIEndpoint = '/app' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubApp] - Done" #endregion - From [functions] - [public] - [Apps] - [Get-GitHubApp] #region - From [functions] - [public] - [Apps] - [Get-GitHubAppInstallation] Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppInstallation] - Importing" filter Get-GitHubAppInstallation { <# .SYNOPSIS List installations for the authenticated app .DESCRIPTION The permissions the installation has are included under the `permissions` key. You must use a [JWT](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app) to access this endpoint. .EXAMPLE An example .NOTES [List installations for the authenticated app](https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app) #> [CmdletBinding()] param() $inputObject = @{ APIEndpoint = '/app/installations' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppInstallation] - Done" #endregion - From [functions] - [public] - [Apps] - [Get-GitHubAppInstallation] #region - From [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken] Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken] - Importing" function Get-GitHubAppJSONWebToken { <# .SYNOPSIS Generates a JSON Web Token (JWT) for a GitHub App. .DESCRIPTION Generates a JSON Web Token (JWT) for a GitHub App. .EXAMPLE Get-GitHubAppJWT -ClientId 'Iv987654321' -PrivateKeyFilePath '/path/to/private-key.pem' Generates a JSON Web Token (JWT) for a GitHub App using the specified client ID and private key file path. .EXAMPLE Get-GitHubAppJWT -ClientId 'Iv987654321' -PrivateKey '--- BEGIN RSA PRIVATE KEY --- ... --- END RSA PRIVATE KEY ---' Generates a JSON Web Token (JWT) for a GitHub App using the specified client ID and private key. .OUTPUTS System.String .NOTES [Generating a JSON Web Token (JWT) for a GitHub App | GitHub Docs](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app#example-using-powershell-to-generate-a-jwt) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Justification = 'Contains a long link.' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Generated JWT is a plaintext string.' )] [CmdletBinding(DefaultParameterSetName = 'PrivateKey')] [Alias('Get-GitHubAppJWT')] [OutputType([string])] param( # The client ID of the GitHub App. # Can use the GitHub App ID or the client ID. # Example: 'Iv23li8tyK9NUwl7rWlQ' # Example: '123456' [Parameter(Mandatory)] [string] $ClientId, # The path to the private key file of the GitHub App. # Example: '/path/to/private-key.pem' [Parameter( Mandatory, ParameterSetName = 'FilePath' )] [string] $PrivateKeyFilePath, # The private key of the GitHub App. # Example: @' # -----BEGIN RSA PRIVATE KEY----- # qwe # ... # -----END RSA PRIVATE KEY----- # '@ [Parameter( Mandatory, ParameterSetName = 'PrivateKey' )] [object] $PrivateKey ) if ($PrivateKeyFilePath) { if (-not (Test-Path -Path $PrivateKeyFilePath)) { throw "The private key path [$PrivateKeyFilePath] does not exist." } $PrivateKey = Get-Content -Path $PrivateKeyFilePath -Raw } if ($PrivateKey -is [securestring]) { $PrivateKey = $PrivateKey | ConvertFrom-SecureString -AsPlainText } $header = [Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes( ( ConvertTo-Json -InputObject @{ alg = 'RS256' typ = 'JWT' } ) ) ).TrimEnd('=').Replace('+', '-').Replace('/', '_') $iat = [System.DateTimeOffset]::UtcNow.AddSeconds(-10).ToUnixTimeSeconds() $exp = [System.DateTimeOffset]::UtcNow.AddMinutes(10).ToUnixTimeSeconds() $payload = [Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes( ( ConvertTo-Json -InputObject @{ iat = $iat exp = $exp iss = $ClientId } ) ) ).TrimEnd('=').Replace('+', '-').Replace('/', '_') $rsa = [System.Security.Cryptography.RSA]::Create() $rsa.ImportFromPem($PrivateKey) $signature = [Convert]::ToBase64String( $rsa.SignData( [System.Text.Encoding]::UTF8.GetBytes("$header.$payload"), [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1 ) ).TrimEnd('=').Replace('+', '-').Replace('/', '_') $jwt = "$header.$payload.$signature" [pscustomobject]@{ Token = ConvertTo-SecureString -String $jwt -AsPlainText IssuedAt = $iat ExpiresAt = $exp Issuer = $ClientId } Remove-Variable -Name jwt -ErrorAction SilentlyContinue Remove-Variable -Name rsa -ErrorAction SilentlyContinue Remove-Variable -Name signature -ErrorAction SilentlyContinue [System.GC]::Collect() } Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken] - Done" #endregion - From [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken] #region - From [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken] Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken] - Importing" filter New-GitHubAppInstallationAccessToken { <# .SYNOPSIS Create an installation access token for an app .DESCRIPTION Creates an installation access token that enables a GitHub App to make authenticated API requests for the app's installation on an organization or individual account. Installation tokens expire one hour from the time you create them. Using an expired token produces a status code of `401 - Unauthorized`, and requires creating a new installation token. By default the installation token has access to all repositories that the installation can access. Optionally, you can use the `repositories` or `repository_ids` body parameters to specify individual repositories that the installation access token can access. If you don't use `repositories` or `repository_ids` to grant access to specific repositories, the installation access token will have access to all repositories that the installation was granted access to. The installation access token cannot be granted access to repositories that the installation was not granted access to. Up to 500 repositories can be listed in this manner. Optionally, use the `permissions` body parameter to specify the permissions that the installation access token should have. If `permissions` is not specified, the installation access token will have all of the permissions that were granted to the app. The installation access token cannot be granted permissions that the app was not granted. When using the repository or permission parameters to reduce the access of the token, the complexity of the token is increased due to both the number of permissions in the request and the number of repositories the token will have access to. If the complexity is too large, the token will fail to be issued. If this occurs, the error message will indicate the maximum number of repositories that should be requested. For the average application requesting 8 permissions, this limit is around 5000 repositories. With fewer permissions requested, more repositories are supported. You must use a [JWT](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app) to access this endpoint. .EXAMPLE New-GitHubAppInstallationAccessToken -InstallationID 12345678 Creates an installation access token for the installation with the ID `12345678`. .EXAMPLE Connect-GitHub -ClientID $ClientID -PrivateKey $PrivateKey -Verbose Get-GitHubAppInstallation | New-GitHubAppInstallationAccessToken Gets the GitHub App installations and creates an installation access token for each installation. .NOTES [Create an installation access token for an app](https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'No state is changed.' )] [CmdletBinding()] param ( # The unique identifier of the installation. # Example: '12345678' [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('ID')] [int] $InstallationID ) $inputObject = @{ APIEndpoint = "/app/installations/$InstallationID/access_tokens" Method = 'Post' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken] - Done" #endregion - From [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken] Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - Done" #endregion - From [functions] - [public] - [Apps] #region - From [functions] - [public] - [Auth] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - Processing folder" #region - From [functions] - [public] - [Auth] - [Context] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - Processing folder" #region - From [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Get-GitHubContext { <# .SYNOPSIS Get the current GitHub context. .DESCRIPTION Get the current GitHub context. .EXAMPLE Get-GitHubContext Gets the current GitHub context. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Encapsulated in a function. Never leaves as a plain text.' )] [OutputType([GitHubContext])] [CmdletBinding(DefaultParameterSetName = 'CurrentContext')] param( # The name of the context. [Parameter( Mandatory, ParameterSetName = 'NamedContext' )] [Alias('Name')] [string] $Context, # List all available contexts. [Parameter( Mandatory, ParameterSetName = 'ListAvailableContexts' )] [switch] $ListAvailable ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" if ($ListAvailable) { $ID = "$($script:Config.Name)/*" Write-Verbose "Getting available contexts for [$ID]" } elseif ($Context) { $ID = "$($script:Config.Name)/$Context" Write-Verbose "Getting available contexts for [$ID]" } else { $config = Get-GitHubConfig $defaultContext = $config.DefaultContext $ID = "$($script:Config.Name)/$defaultContext" if ([string]::IsNullOrEmpty($ID)) { throw "No default GitHub context found. Please run 'Set-GitHubDefaultContext' or 'Connect-GitHub' to configure a GitHub context." } Write-Verbose "Getting the default context: [$ID]" } Get-Context -ID $ID | ForEach-Object { [GitHubContext]$_ } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext] - Done" #endregion - From [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext] #region - From [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } filter Remove-GitHubContext { <# .SYNOPSIS Removes a context from the context vault. .DESCRIPTION This function removes a context from the vault. It supports removing a single context by name, multiple contexts using wildcard patterns, and can also accept input from the pipeline. If the specified context(s) exist, they will be removed from the vault. .EXAMPLE Remove-Context Removes all contexts from the vault. .EXAMPLE Remove-Context -ID 'MySecret' Removes the context called 'MySecret' from the vault. #> [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] param( # The name of the context. [Parameter(Mandatory)] [Alias('Name')] [string] $Context ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" $ID = "$($script:Config.Name)/$Context" if ($PSCmdlet.ShouldProcess('Remove-Secret', $context.Name)) { Remove-Context -ID $ID } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext] - Done" #endregion - From [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext] #region - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Set-GitHubContext { <# .SYNOPSIS Short description .DESCRIPTION Long description .EXAMPLE An example .NOTES General notes #> [CmdletBinding(SupportsShouldProcess)] param ( # The Node ID of the context. [Parameter()] [string] $NodeID, # The Database ID of the context. [Parameter()] [string] $DatabaseID, # Set the access token type. [Parameter(Mandatory)] [string] $TokenType, # Set the client ID. [Parameter()] [string] $ClientID, # Set the access token. [Parameter(Mandatory)] [securestring] $Token, # Set the expiration date of the contexts token. [Parameter()] [datetime] $TokenExpirationDate, # Set the API Base URI. [Parameter(Mandatory)] [string] $ApiBaseUri, # Set the GitHub API Version. [Parameter(Mandatory)] [string] $ApiVersion, # Set the authentication client ID. [Parameter()] [string] $AuthClientID, # Set the authentication type. [Parameter(Mandatory)] [string] $AuthType, # Set the device flow type. [Parameter()] [string] $DeviceFlowType, # Set the API hostname. [Parameter(Mandatory)] [string] $HostName, # 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 as the default context. [Parameter()] [switch] $Default ) begin { $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" } process { $tempContextName = "$HostName/tempContext" $tempContextID = "$($script:Config.Name)/$tempContextName" # Set a temporary context. $context = @{ ApiBaseUri = $ApiBaseUri # https://api.github.com ApiVersion = $ApiVersion # 2022-11-28 AuthClientID = $AuthClientID # Client ID for UAT AuthType = $AuthType # UAT / PAT / App / IAT ClientID = $ClientID # Client ID for GitHub Apps DeviceFlowType = $DeviceFlowType # GitHubApp / OAuthApp HostName = $HostName # github.com / msx.ghe.com / github.local NodeID = $NodeID # User ID / app ID (GraphQL Node ID) DatabaseID = $DatabaseID # Database ID UserName = $UserName # User name Owner = $Owner # Owner name Repo = $Repo # Repo name Scope = $Scope # 'gist read:org repo workflow' #----------------------------------------------------------------------------------------- TokenType = $TokenType # ghu / gho / ghp / github_pat / PEM / ghs / Token = $Token # Access token TokenExpirationDate = $TokenExpirationDate # 2024-01-01-00:00:00 RefreshToken = $RefreshToken # Refresh token RefreshTokenExpirationDate = $RefreshTokenExpirationDate # 2024-01-01-00:00:00 } $context | Remove-HashtableEntry -NullOrEmptyValues Set-Context -ID $tempContextID -Context $context # Run functions to get info on the temporary context. try { Write-Verbose 'Getting info on the context.' switch -Regex ($context['AuthType']) { 'PAT|UAT|IAT' { $viewer = Get-GitHubViewer -Context $tempContextName $contextName = "$HostName/$($viewer.login)" $context['Username'] = $viewer.login $context['NodeID'] = $viewer.id $context['DatabaseID'] = ($viewer.databaseId).ToString() } 'App' { $app = Get-GitHubApp -Context $tempContextName $contextName = "$HostName/$($app.slug)" $context['Username'] = $app.slug $context['NodeID'] = $app.node_id $context['DatabaseID'] = $app.id } default { throw 'Failed to get info on the context. Unknown logon type.' } } Write-Verbose "Found user with username: [$($context['Username'])]" if ($PSCmdlet.ShouldProcess('Context', 'Set')) { Set-Context -ID "$($script:Config.Name)/$contextName" -Context $context if ($Default) { Set-GitHubDefaultContext -Context $contextName if ($context['AuthType'] -eq 'IAT' -and $script:runEnv -eq 'GHA') { Set-GitHubGitConfig -Context $contextName } } } } catch { throw ($_ -join ';') } finally { Remove-Context -ID $tempContextID } } end { Write-Verbose "[$commandName] - End" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext] - Done" #endregion - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext] #region - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext] - Importing" function Set-GitHubDefaultContext { <# .SYNOPSIS Set the default context. .DESCRIPTION Set the default context for the GitHub module. .EXAMPLE Set-GitHubDefaultContext -Context 'github.com/Octocat' #> [CmdletBinding(SupportsShouldProcess)] param ( # The context to set as the default. [Parameter(Mandatory)] [Alias('Name')] [string] $Context ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" if ($PSCmdlet.ShouldProcess("$Context", 'Set default context')) { Set-GitHubConfig -Name 'DefaultContext' -Value $Context } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext] - Done" #endregion - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - Done" #endregion - From [functions] - [public] - [Auth] - [Context] #region - From [functions] - [public] - [Auth] - [ContextSetting] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - Processing folder" #region - From [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Get-GitHubContextSetting { <# .SYNOPSIS Get a module configuration value. .DESCRIPTION Get a named configuration value from the GitHub config. .EXAMPLE Get-GitHubContextSetting -Name DefaultUser Get the current GitHub configuration for the DefaultUser. #> [OutputType([object])] [CmdletBinding()] param( # Choose a configuration name to get. [Parameter()] [string] $Name, # The name of the context. [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" $ID = "$($script:Config.Name)/$Context" if (-not $Name) { Get-Context -ID $ID } Get-ContextSetting -Name $Name -ID $ID Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting] - Done" #endregion - From [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting] #region - From [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Set-GitHubContextSetting { <# .SYNOPSIS Set the GitHub configuration. .DESCRIPTION Set the GitHub configuration. Specific scopes can be set by using the parameters. .EXAMPLE Set-GitHubContextSetting -APIBaseURI 'https://api.github.com" -APIVersion '2022-11-28' Sets the App.API scope of the GitHub configuration. .EXAMPLE Set-GitHubContextSetting -Name "MyFavouriteRepo" -Value 'https://github.com/PSModule/GitHub' Sets a item called 'MyFavouriteRepo' in the GitHub configuration. #> [Alias('Set-GHConfig')] [CmdletBinding(SupportsShouldProcess)] param ( # Set the access token type. [Parameter()] [string] $TokenType, # The Node ID of the context. [Parameter()] [string] $NodeID, # The Database ID of the context. [Parameter()] [string] $DatabaseID, # Set the access token. [Parameter()] [securestring] $Token, # Set the access token expiration date. [Parameter()] [datetime] $TokenExpirationDate, # Set the API Base URI. [Parameter()] [string] $ApiBaseUri, # Set the GitHub API Version. [Parameter()] [string] $ApiVersion, # Set the authentication client ID. [Parameter()] [string] $AuthClientID, # Set the authentication type. [Parameter()] [string] $AuthType, # Set the client ID. [Parameter()] [string] $ClientID, # 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, # The context name to set the configuration for. [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" $contextID = "$($Script:Config.Name)/$Context" if ($PSCmdlet.ShouldProcess('Config', 'Set')) { $PSBoundParameters.GetEnumerator() | ForEach-Object { $key = $_.Key $value = $_.Value if ($PSCmdlet.ShouldProcess("Setting [$key]", "to [$value]")) { Write-Verbose "Setting [$key] to [$value]" Set-ContextSetting -Name $key -Value $value -ID $contextID } } } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting] - Done" #endregion - From [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - Done" #endregion - From [functions] - [public] - [Auth] - [ContextSetting] #region - From [functions] - [public] - [Auth] - [Connect-GitHubAccount] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Connect-GitHubAccount] - Importing" function Connect-GitHubAccount { <# .SYNOPSIS Connects to GitHub. .DESCRIPTION Connects to GitHub using one of the following logon methods: - a personal access token - device code login (interactive user login) - a system access token (for GitHub Actions) - a GitHub App using JWT or installation access token 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 $env:GH_TOKEN = '***' Connect-GitHubAccount Connects to GitHub using the access token from environment variable, assuming unattended mode. .EXAMPLE Connect-GitHubAccount -UseAccessToken ! Enter your personal access token: ************* User gets prompted for the access token and stores it in the context. 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 [Authenticating to the REST API](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])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Is the CLI part of the module.')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'The tokens are recieved as clear text. Mitigating exposure by removing variables and performing garbage collection.')] [CmdletBinding(DefaultParameterSetName = 'UAT')] param ( # Choose between authentication methods, either OAuthApp or GitHubApp. # For more info about the types of authentication visit: # [Differences between GitHub Apps and OAuth apps](https://docs.github.com/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps) [Parameter(ParameterSetName = 'UAT')] [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: # [Scopes for OAuth apps](https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps) [Parameter(ParameterSetName = 'UAT')] [string] $Scope = 'gist read:org repo workflow', # The user will be prompted to enter the token. [Parameter( Mandatory, ParameterSetName = 'PAT' )] [switch] $UseAccessToken, # An access token to use for authentication. Can be both a string or a SecureString. # Supports both personal access tokens (PAT) and GitHub App installation access tokens (IAT). # Example: 'ghp_1234567890abcdef' # Example: 'ghs_1234567890abcdef' [Parameter( Mandatory, ParameterSetName = 'Token' )] [object] $Token, # The client ID for the GitHub App to use for authentication. [Parameter(ParameterSetName = 'UAT')] [Parameter( Mandatory, ParameterSetName = 'App' )] [string] $ClientID, # The private key for the GitHub App when authenticating as a GitHub App. [Parameter( Mandatory, ParameterSetName = 'App' )] [string] $PrivateKey, # Set the default owner to use in commands. [Parameter()] [Alias('Organization')] [Alias('Org')] [string] $Owner = $env:GITHUB_REPOSITORY_OWNER, # Set the default repository to use in commands. [Parameter()] [Alias('Repository')] [string] $Repo = $env:GITHUB_REPOSITORY_NAME, # API version used for API requests. [Parameter()] [string] $ApiVersion = '2022-11-28', # The host to connect to. Can use $env:GITHUB_SERVER_URL to set the host, as the protocol is removed automatically. # Example: github.com, github.enterprise.com, msx.ghe.com [Parameter()] [Alias('Host')] [Alias('Server')] [string] $HostName = $env:GITHUB_SERVER_URL ?? 'github.com', # Suppresses the output of the function. [Parameter()] [Alias('Quiet')] [Alias('q')] [Alias('s')] [switch] $Silent ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" try { if ($Token -is [System.Security.SecureString]) { $Token = ConvertFrom-SecureString $Token -AsPlainText } $HostName = $HostName -replace '^https?://' $ApiBaseUri = "https://api.$HostName" $authType = $PSCmdlet.ParameterSetName $tokenPrefixPattern = '(?<=^(ghu|gho|ghs|github_pat|ghp)).*' # If running on GitHub Actions and no access token is provided, use the GitHub token. if (($env:GITHUB_ACTIONS -eq 'true') -and $PSCmdlet.ParameterSetName -ne 'App') { $tokenNotProvided = [string]::IsNullOrEmpty($Token) $gitHubToken = $env:GH_TOKEN ?? $env:GITHUB_TOKEN $gitHubTokenPresent = -not [string]::IsNullOrEmpty($gitHubToken) Write-Verbose "Token not provided: [$tokenNotProvided]" Write-Verbose "GitHub token present: [$gitHubTokenPresent]" if ($tokenNotProvided -and $gitHubTokenPresent) { $authType = 'Token' $Token = $gitHubToken } } $context = @{ ApiBaseUri = $ApiBaseUri ApiVersion = $ApiVersion HostName = $HostName AuthType = $authType Owner = $Owner Repo = $Repo } $gitHubConfig = Get-GitHubConfig $defaultContextID = $gitHubConfig.DefaultContext if ($defaultContextID) { $defaultContext = Get-GitHubContext -Context $defaultContextID } Write-Verbose "AuthType: [$authType]" switch ($authType) { 'UAT' { Write-Verbose 'Logging in using device flow...' if (-not [string]::IsNullOrEmpty($ClientID)) { Write-Verbose "Using provided ClientID: [$ClientID]" $authClientID = $ClientID } elseif (-not [string]::IsNullOrEmpty($($defaultContext.AuthClientID))) { Write-Verbose "Reusing previously stored ClientID: [$($defaultContext.AuthClientID)]" $authClientID = $defaultContext.AuthClientID } else { Write-Verbose "Using default ClientID: [$($script:Auth.$Mode.ClientID)]" $authClientID = $script:Auth.$Mode.ClientID } if ($Mode -ne ($defaultContext.DeviceFlowType)) { Write-Verbose "Using $Mode authentication..." $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $authClientID -Scope $Scope -HostName $HostName } else { $accessTokenValidity = [datetime]($defaultContext.TokenExpirationDate) - (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 ..." } return } else { if (-not $Silent) { Write-Host 'âš ' -ForegroundColor Yellow -NoNewline Write-Host "Access token remaining validity $accessTokenValidityText. Refreshing access token..." } $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $authClientID -RefreshToken ($defaultContext.RefreshToken) -HostName $HostName } } else { $refreshTokenValidity = [datetime]($defaultContext.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 $authClientID -RefreshToken ($defaultContext.RefreshToken) -HostName $HostName } else { Write-Verbose "Using $Mode authentication..." $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $authClientID -Scope $Scope -HostName $HostName } } } switch ($Mode) { 'GitHubApp' { $context += @{ Token = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token TokenExpirationDate = (Get-Date).AddSeconds($tokenResponse.expires_in) TokenType = $tokenResponse.access_token -replace $tokenPrefixPattern AuthClientID = $authClientID DeviceFlowType = $Mode RefreshToken = ConvertTo-SecureString -AsPlainText $tokenResponse.refresh_token RefreshTokenExpirationDate = (Get-Date).AddSeconds($tokenResponse.refresh_token_expires_in) Scope = $tokenResponse.scope } } 'OAuthApp' { $context += @{ Token = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token TokenType = $tokenResponse.access_token -replace $tokenPrefixPattern AuthClientID = $authClientID DeviceFlowType = $Mode Scope = $tokenResponse.scope } } default { Write-Host 'âš ' -ForegroundColor Yellow -NoNewline Write-Host "Unexpected authentication mode: $Mode" return } } } 'App' { Write-Verbose 'Logging in as a GitHub App...' $context += @{ Token = ConvertTo-SecureString -AsPlainText $PrivateKey TokenType = 'PEM' ClientID = $ClientID } } 'PAT' { Write-Debug "UseAccessToken is set to [$UseAccessToken]. Using provided access token..." Write-Verbose 'Logging in using personal access token...' Write-Host '! ' -ForegroundColor DarkYellow -NoNewline Start-Process "https://$HostName/settings/tokens" $accessTokenValue = Read-Host -Prompt 'Enter your personal access token' -AsSecureString $Token = ConvertFrom-SecureString $accessTokenValue -AsPlainText $tokenType = $Token -replace $tokenPrefixPattern $context += @{ Token = ConvertTo-SecureString -AsPlainText $Token TokenType = $tokenType } } 'Token' { $tokenType = $Token -replace $tokenPrefixPattern switch -Regex ($tokenType) { 'ghp|github_pat' { $context += @{ Token = ConvertTo-SecureString -AsPlainText $Token TokenType = $tokenType } $context['AuthType'] = 'PAT' } 'ghs' { Write-Verbose 'Logging in using an installation access token...' $context += @{ Token = ConvertTo-SecureString -AsPlainText $Token TokenType = $tokenType } $context['AuthType'] = 'IAT' } default { Write-Host 'âš ' -ForegroundColor Yellow -NoNewline Write-Host "Unexpected token type: $tokenType" throw "Unexpected token type: $tokenType" } } } } Set-GitHubContext @context -Default $context = Get-GitHubContext Write-Verbose ($context | Format-List | Out-String) if (-not $Silent) { $name = $context.Username Write-Host '✓ ' -ForegroundColor Green -NoNewline Write-Host "Logged in as $name!" } } catch { Write-Error $_ Write-Error (Get-PSCallStack | Format-Table | Out-String) throw 'Failed to connect to GitHub.' } finally { Remove-Variable -Name tokenResponse -ErrorAction SilentlyContinue Remove-Variable -Name context -ErrorAction SilentlyContinue [System.GC]::Collect() } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Connect-GitHubAccount] - Done" #endregion - From [functions] - [public] - [Auth] - [Connect-GitHubAccount] #region - From [functions] - [public] - [Auth] - [Disconnect-GitHubAccount] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Disconnect-GitHubAccount] - Importing" function Disconnect-GitHubAccount { <# .SYNOPSIS Disconnects from GitHub and removes the GitHub context. .DESCRIPTION Disconnects from GitHub and removes the GitHub context. .EXAMPLE Disconnect-GitHubAccount Disconnects from GitHub and removes the default GitHub context. .EXAMPLE Disconnect-GithubAccount -Context 'github.com/Octocat' Disconnects from GitHub and removes the context 'github.com/Octocat'. #> [Alias( 'Disconnect-GHAccount', 'Disconnect-GitHub', 'Disconnect-GH', 'Logout-GitHubAccount', 'Logout-GHAccount', 'Logout-GitHub', 'Logout-GH', 'Logoff-GitHubAccount', 'Logoff-GHAccount', 'Logoff-GitHub', 'Logoff-GH' )] [OutputType([void])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Is the CLI part of the module.')] [CmdletBinding()] param( # The context to log out of. [Parameter()] [Alias('Name')] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext'), # Silently disconnects from GitHub. [Parameter()] [switch] $Silent ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" Remove-GitHubContext -Context $Context $isDefaultContext = $Context -eq (Get-GitHubConfig -Name 'DefaultContext') if ($isDefaultContext) { Remove-GitHubConfig -Name 'DefaultContext' } if (-not $Silent) { Write-Host '✓ ' -ForegroundColor Green -NoNewline Write-Host "Logged out of GitHub! [$Context]" } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Disconnect-GitHubAccount] - Done" #endregion - From [functions] - [public] - [Auth] - [Disconnect-GitHubAccount] #region - From [functions] - [public] - [Auth] - [Get-GitHubViewer] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Get-GitHubViewer] - Importing" function Get-GitHubViewer { <# .SYNOPSIS Gets the currently authenticated user. .DESCRIPTION Gets the currently authenticated user. .EXAMPLE Get-GithubViewer Gets the currently authenticated user. .NOTES [GraphQL API - Queries - Viewer](https://docs.github.com/en/graphql/reference/queries#viewer) #> [CmdletBinding()] param( # The fields to return. [string[]] $Fields = @('login', 'id', 'databaseId'), # Context to run the command in. [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) begin { $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" } process { $query = @" query { viewer { $($Fields -join "`n") } } "@ $results = Invoke-GitHubGraphQLQuery -Query $query -Context $Context return $results.data.viewer } end { Write-Verbose "[$commandName] - End" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Get-GitHubViewer] - Done" #endregion - From [functions] - [public] - [Auth] - [Get-GitHubViewer] Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - Done" #endregion - From [functions] - [public] - [Auth] #region - From [functions] - [public] - [Branches] Write-Verbose "[$scriptName] - [functions] - [public] - [Branches] - Processing folder" #region - From [functions] - [public] - [Branches] - [Get-GitHubRepoBranch] Write-Verbose "[$scriptName] - [functions] - [public] - [Branches] - [Get-GitHubRepoBranch] - Importing" filter Get-GitHubRepoBranch { <# .SYNOPSIS List branches .DESCRIPTION Lists all branches from a repository .EXAMPLE Get-GitHubRepoBranch -Owner 'octocat' -Repo 'Hello-World' Gets all the branches from the 'Hello-World' repository owned by 'octocat' .NOTES [List branches](https://docs.github.com/rest/branches/branches#list-branches) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/branches" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Branches] - [Get-GitHubRepoBranch] - Done" #endregion - From [functions] - [public] - [Branches] - [Get-GitHubRepoBranch] Write-Verbose "[$scriptName] - [functions] - [public] - [Branches] - Done" #endregion - From [functions] - [public] - [Branches] #region - From [functions] - [public] - [Commands] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - Processing folder" #region - From [functions] - [public] - [Commands] - [Add-GitHubMask] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubMask] - Importing" filter Add-GitHubMask { <# .SYNOPSIS Masks a value in a log .DESCRIPTION Masking a value prevents a string or variable from being printed in the log. Each masked word separated by whitespace is replaced with the * character. You can use an environment variable or string for the mask's value. When you mask a value, it is treated as a secret and will be redacted on the runner. For example, after you mask a value, you won't be able to set that value as an output. .EXAMPLE Add-Mask $SecretValue Masks the value of $SecretValue so that its printed like ***. .EXAMPLE $SecretValue1, $SecretValue2 | Mask Masks the value of $SecretValue1 and $SecretValue2 so that its printed like ***, using the pipeline .NOTES [Masking a value in a log](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#masking-a-value-in-a-log) #> [Alias('Mask', 'Add-Mask')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long documentation URL' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change state' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners which does support Write-Host' )] [CmdletBinding()] param( # The value to mask [Parameter( Mandatory, ValueFromPipeline )] [AllowNull()] [string[]] $Value ) foreach ($item in $Value) { Write-Host "::add-mask::$item" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubMask] - Done" #endregion - From [functions] - [public] - [Commands] - [Add-GitHubMask] #region - From [functions] - [public] - [Commands] - [Add-GitHubSystemPath] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubSystemPath] - Importing" function Add-GitHubSystemPath { <# .SYNOPSIS Adds a system path to the GitHub Actions environment .DESCRIPTION Prepends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job; the currently running action cannot access the updated path variable. To see the currently defined paths for your job, you can use echo "$env:PATH" in a step or an action. .EXAMPLE Add-GitHubSystemPath -Path '$HOME/.local/bin' .NOTES [Adding a system path](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-system-path) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long documentation URL' )] [OutputType([void])] [CmdletBinding()] param ( [string]$Path ) Write-Verbose "Current PATH: $env:PATH" Write-Verbose "Adding system path: $Path" $Path | Out-File -FilePath $env:GITHUB_PATH -Append } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubSystemPath] - Done" #endregion - From [functions] - [public] - [Commands] - [Add-GitHubSystemPath] #region - From [functions] - [public] - [Commands] - [Disable-GitHubCommand] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Disable-GitHubCommand] - Importing" function Disable-GitHubCommand { <# .SYNOPSIS Stops workflow commands .DESCRIPTION Stops processing any workflow commands. This special command allows you to log anything without accidentally running a workflow command. For example, you could stop logging to output an entire script that has comments. To stop the processing of workflow commands, pass a unique string to the function. To resume processing workflow commands, pass the same string that you used to stop workflow commands to the Enable-GitHubCommand. .EXAMPLE Disable-GitHubCommand "123" Stops processing any workflow commands. .NOTES [Stopping and starting workflow commands](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#stopping-and-starting-workflow-commands) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners which does support Write-Host' )] [OutputType([void])] [CmdletBinding()] param ( # The unique string to stop the processing of workflow commands [Parameter(Mandatory)] [string] $String ) $String = $String.ToLower() if ($env:GITHUB_ACTIONS -eq 'true') { Write-Host "::stop-commands::$String" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Disable-GitHubCommand] - Done" #endregion - From [functions] - [public] - [Commands] - [Disable-GitHubCommand] #region - From [functions] - [public] - [Commands] - [Enable-GitHubCommand] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Enable-GitHubCommand] - Importing" function Enable-GitHubCommand { <# .SYNOPSIS Resumes workflow commands .DESCRIPTION Resumes processing any workflow commands. To stop the processing of workflow commands, pass a unique string to the function. To resume processing workflow commands, pass the same string that you used to stop workflow commands to the Enable-GitHubCommand. .EXAMPLE Enable-GitHubCommand "123" Resumes processing any workflow commands. .NOTES [Stopping and starting workflow commands](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#stopping-and-starting-workflow-commands) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners which does support Write-Host' )] [OutputType([void])] [CmdletBinding()] param ( # The unique string to resume the processing of workflow commands [Parameter(Mandatory)] [string] $String ) $String = $String.ToLower() if ($env:GITHUB_ACTIONS -eq 'true') { Write-Host "::$String::" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Enable-GitHubCommand] - Done" #endregion - From [functions] - [public] - [Commands] - [Enable-GitHubCommand] #region - From [functions] - [public] - [Commands] - [Get-GitHubOutput] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Get-GitHubOutput] - Importing" function Get-GitHubOutput { <# .SYNOPSIS Gets the GitHub output. .DESCRIPTION Gets the GitHub output from $env:GITHUB_OUTPUT and creates an object with key-value pairs, supporting both single-line and multi-line values .EXAMPLE Get-GitHubOutput MY_VALUE result zen -------- ------ --- qwe… @{"MyOutput":"Hello, World!"} something else Gets the GitHub output and returns an object with key-value pairs. .EXAMPLE Get-GitHubOutput -AsHashtable Name Value ---- ----- MyArray 1 2 3 MyOutput Hello, World! zen something else result {[thisisatest, a simple value]} mystuff {[MyOutput, Hello, World!]} MY_VALUE qwe… Gets the GitHub output and returns a hashtable. #> [OutputType([pscustomobject])] [CmdletBinding()] param( # Returns the output as a hashtable. [Parameter()] [switch] $AsHashtable, # The path to the GitHub output file. [Parameter()] [string] $Path = $env:GITHUB_OUTPUT ) if (-not (Test-Path -Path $Path)) { throw "File not found: $Path" } Get-Content -Path $Path | ConvertFrom-GitHubOutput -AsHashtable:$AsHashtable } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Get-GitHubOutput] - Done" #endregion - From [functions] - [public] - [Commands] - [Get-GitHubOutput] #region - From [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable] - Importing" function Set-GitHubEnvironmentVariable { <# .SYNOPSIS Setting an environment variable .DESCRIPTION Set a GitHub environment variable .EXAMPLE Set-GitHubEnv -Name 'MyVariable' -Value 'MyValue' .NOTES [Setting an environment variable](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-environment-variable) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change system state significantly' )] [OutputType([void])] [Alias('Set-GitHubEnv')] [CmdletBinding()] param ( # Name of the variable [Parameter(Mandatory)] [string] $Name, # Value of the variable [Parameter(Mandatory)] [AllowNull()] [string] $Value ) Write-Verbose "Env: [$Name] = [$Value]" $guid = [guid]::NewGuid().Guid $content = @" $Name<<$guid $Value $guid "@ $content | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable] - Done" #endregion - From [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable] #region - From [functions] - [public] - [Commands] - [Set-GitHubLogGroup] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubLogGroup] - Importing" function Set-GitHubLogGroup { <# .SYNOPSIS Encapsulates commands with a log group in GitHub Actions .DESCRIPTION DSL approach for GitHub Action commands. Allows for colapsing of code in IDE for code that belong together. .EXAMPLE Set-GitHubLogGroup -Name 'MyGroup' -ScriptBlock { Write-Host 'Hello, World!' } Creates a new log group named 'MyGroup' and writes 'Hello, World!' to the output. .EXAMPLE LogGroup 'MyGroup' { Write-Host 'Hello, World!' } Uses the alias 'LogGroup' to create a new log group named 'MyGroup' and writes 'Hello, World!' to the output. .NOTES [GitHub - Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines) #> [Alias('LogGroup')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change state' )] [CmdletBinding()] param( # The name of the log group [Parameter(Mandatory)] [string] $Name, # The script block to execute [Parameter(Mandatory)] [scriptblock] $ScriptBlock ) Start-GitHubLogGroup -Name $Name . $ScriptBlock Stop-GitHubLogGroup } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubLogGroup] - Done" #endregion - From [functions] - [public] - [Commands] - [Set-GitHubLogGroup] #region - From [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup] - Importing" function Set-GitHubNoCommandGroup { <# .SYNOPSIS Disables workflow commands for a block of code. .DESCRIPTION DSL approach for GitHub Action commands. Allows for colapsing of code in IDE for code that belong together. .EXAMPLE Set-GitHubNoCommandGroup { Write-Host 'Hello, World!' Write-GithubError 'This is an error' } Groups commands where no workflow commands are run. .EXAMPLE NoLogGroup 'MyGroup' { Write-Host 'Hello, World!' Write-GithubError 'This is an error' } Groups commands where no workflow commands are run, using an alias and DSL approach. .NOTES [Stopping and starting workflow commands](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#stopping-and-starting-workflow-commands) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change state' )] [CmdletBinding()] [Alias('NoLogGroup')] param( # The script block to execute [Parameter(Mandatory)] [scriptblock] $ScriptBlock ) $guid = [string][guid]::NewGuid().Guid Disable-GitHubCommand -String $guid . $ScriptBlock Enable-GitHubCommand -String $guid } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup] - Done" #endregion - From [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup] #region - From [functions] - [public] - [Commands] - [Set-GitHubOutput] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubOutput] - Importing" function Set-GitHubOutput { <# .SYNOPSIS Sets the GitHub output for a given key and value. .DESCRIPTION This function appends key-value pairs to the GitHub Actions output file specified by $env:GITHUB_OUTPUT. It handles two scenarios: - Normal shell execution: Appends the key-value pair directly. - GitHub composite action via [GitHub-Script](https://github.com/PSModule/GitHub-Script): Accumulates key-value pairs under the 'result' key as a JSON object. .EXAMPLE Set-GitHubOutput -Name 'ID' -Value '123123123' Sets the output variable 'ID' to '123123123' in the GitHub Actions output file. .EXAMPLE Set-GitHubOutput -Name 'result' -Value @{ ID = '123123123' name = 'test' } #> [CmdletBinding(SupportsShouldProcess)] param( # The name of the output variable to set. [Parameter(Mandatory)] [string] $Name, # The value of the output variable to set. [Parameter(Mandatory)] [object] $Value, # The path to the GitHub output file. [Parameter()] [string] $Path = $env:GITHUB_OUTPUT ) if (-not (Test-Path -Path $Path)) { throw "File not found: $Path" } $outputs = Get-GithubOutput -Path $Path -AsHashtable if ($Value -Is [securestring]) { $Value = $Value | ConvertFrom-SecureString -AsPlainText -Force Add-Mask -Value $Value } if ([string]::IsNullOrEmpty($env:GITHUB_ACTION)) { Write-Warning 'Cannot create output as the step has no ID.' } Write-Verbose "Output: [$Name] = [$Value]" # If the script is running in a GitHub composite action, accumulate the output under the 'result' key, else append the key-value pair directly. if ($env:PSMODULE_GITHUB_SCRIPT) { if (-not $outputs.result) { $outputs.result = @{ $Name = $Value } } else { $outputs.result[$Name] = $Value } } else { $outputs[$Name] = $Value } Write-Verbose "Output: [$Name] avaiable as `${{ steps.$env:GITHUB_ACTION.outputs.$Name }}'" if ($PSCmdlet.ShouldProcess('GitHub Output', 'Set')) { $outputs | ConvertTo-GitHubOutput | Set-Content -Path $Path } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubOutput] - Done" #endregion - From [functions] - [public] - [Commands] - [Set-GitHubOutput] #region - From [functions] - [public] - [Commands] - [Set-GitHubStepSummary] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubStepSummary] - Importing" function Set-GitHubStepSummary { <# .SYNOPSIS Set a summary for the step in GitHub Actions .DESCRIPTION You can set some custom Markdown for each job so that it will be displayed on the summary page of a workflow run. You can use job summaries to display and group unique content, such as test result summaries, so that someone viewing the result of a workflow run doesn't need to go into the logs to see important information related to the run, such as failures. Job summaries support GitHub flavored Markdown, and you can add your Markdown content for a step to the `GITHUB_STEP_SUMMARY` environment file. `GITHUB_STEP_SUMMARY` is unique for each step in a job. For more information about the per-step file that `GITHUB_STEP_SUMMARY` references, see [Environment files](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions?utm_source=chatgpt.com#environment-files). When a job finishes, the summaries for all steps in a job are grouped together into a single job summary and are shown on the workflow run summary page. If multiple jobs generate summaries, the job summaries are ordered by job completion time. .EXAMPLE Set-GitHubStepSummary -Summary 'Hello, World!' .NOTES [Adding a job summary](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions?utm_source=chatgpt.com#adding-a-job-summary) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change system state significantly' )] [OutputType([void])] [Alias('Summary')] [CmdletBinding()] param ( # Summary of the step [Parameter(Mandatory)] [AllowNull()] [string] $Summary, # Whether to overwrite the existing summary [switch] $Overwrite ) Write-Verbose 'Step summary:' Write-Verbose $Summary $Append = -not $Overwrite $Summary | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append:$Append } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubStepSummary] - Done" #endregion - From [functions] - [public] - [Commands] - [Set-GitHubStepSummary] #region - From [functions] - [public] - [Commands] - [Start-GitHubLogGroup] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Start-GitHubLogGroup] - Importing" function Start-GitHubLogGroup { <# .SYNOPSIS Starts a log group in GitHub Actions .EXAMPLE New-LogGroup 'MyGroup' Starts a new log group named 'MyGroup' .NOTES [GitHub - Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change state' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners which does support Write-Host' )] [CmdletBinding()] [Alias('Start-LogGroup')] param( # The name of the log group [Parameter(Mandatory)] [string] $Name ) Write-Host "::group::$Name" } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Start-GitHubLogGroup] - Done" #endregion - From [functions] - [public] - [Commands] - [Start-GitHubLogGroup] #region - From [functions] - [public] - [Commands] - [Stop-GitHubLogGroup] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Stop-GitHubLogGroup] - Importing" function Stop-GitHubLogGroup { <# .SYNOPSIS Stops the current log group in GitHub Actions .EXAMPLE Stop-LogGroup Starts a new log group named 'MyGroup' .NOTES [GitHub - Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function', Justification = 'Does not change state' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners' )] [CmdletBinding()] [Alias('Stop-LogGroup')] param() Write-Host '::endgroup::' } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Stop-GitHubLogGroup] - Done" #endregion - From [functions] - [public] - [Commands] - [Stop-GitHubLogGroup] #region - From [functions] - [public] - [Commands] - [Write-GitHubDebug] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubDebug] - Importing" function Write-GitHubDebug { <# .SYNOPSIS Write a debug message in GitHub Actions .DESCRIPTION Write a debug message in GitHub Actions. The message will only be displayed if the action is running in debug mode. To run in debug mode, you must create a secret or variable named ACTIONS_STEP_DEBUG with the value `true` to see the debug messages set by this command in the log. For more information, see [Enabling debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging). If both the secret and variable are set, the value of the secret takes precedence over the variable. .EXAMPLE Write-GitHubDebug -Message 'Hello, World!' Writes a debug message 'Hello, World!'. .NOTES [Enabling debug logging](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-a-debug-message) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners' )] [OutputType([void])] [Alias('Debug')] [CmdletBinding()] param ( # Message to write [Parameter(Mandatory)] [string] $Message ) if ($env:GITHUB_ACTIONS -eq 'true') { Write-Host "::debug::$Message" } else { Write-Debug "$Message" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubDebug] - Done" #endregion - From [functions] - [public] - [Commands] - [Write-GitHubDebug] #region - From [functions] - [public] - [Commands] - [Write-GitHubError] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubError] - Importing" function Write-GitHubError { <# .SYNOPSIS Write a error message in GitHub Actions .DESCRIPTION Write a error message in GitHub Actions. The message will be displayed in the GitHub Actions log. .EXAMPLE Write-GitHubError -Message 'Hello, World!' Writes a error message 'Hello, World!'. .NOTES [Enabling debug logging](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-error-message) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners' )] [OutputType([void])] [Alias('Error')] [CmdletBinding()] param ( # Message to write [Parameter(Mandatory)] [string] $Message, # The name of the file that this error is related to [Parameter()] [string] $Name, # The line number that this error is related to [Parameter()] [int] $Line, # The column number that this error is related to [Parameter()] [int] $Column, # The end column number that this error is related to [Parameter()] [int] $EndColumn, # The end line number that this error is related to [Parameter()] [int] $EndLine, # The title of the error [Parameter()] [string] $Title ) if ($env:GITHUB_ACTIONS -eq 'true') { Write-Host "::error file=$Name,line=$Line,col=$Column,endColumn=$EndColumn,endLine=$EndLine,title=$Title::$Message" } else { Write-Error $Message } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubError] - Done" #endregion - From [functions] - [public] - [Commands] - [Write-GitHubError] #region - From [functions] - [public] - [Commands] - [Write-GitHubNotice] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubNotice] - Importing" function Write-GitHubNotice { <# .SYNOPSIS Write a notice message in GitHub Actions .DESCRIPTION Write a notice message in GitHub Actions. The message will be displayed in the GitHub Actions log. .EXAMPLE Write-GitHubNotice -Message 'Hello, World!' Writes a notice message 'Hello, World!'. .NOTES [Enabling debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners' )] [OutputType([void])] [Alias('Notice')] [CmdletBinding()] param ( # Message to write [Parameter(Mandatory)] [string] $Message, # The name of the file that this notice is related to [Parameter()] [string] $Name, # The line number that this notice is related to [Parameter()] [int] $Line, # The column number that this notice is related to [Parameter()] [int] $Column, # The end column number that this notice is related to [Parameter()] [int] $EndColumn, # The end line number that this notice is related to [Parameter()] [int] $EndLine, # The title of the notice [Parameter()] [string] $Title ) if ($env:GITHUB_ACTIONS -eq 'true') { Write-Host "::notice file=$Name,line=$Line,col=$Column,endColumn=$EndColumn,endLine=$EndLine,title=$Title::$Message" } else { Write-Host $Message } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubNotice] - Done" #endregion - From [functions] - [public] - [Commands] - [Write-GitHubNotice] #region - From [functions] - [public] - [Commands] - [Write-GitHubWarning] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubWarning] - Importing" function Write-GitHubWarning { <# .SYNOPSIS Write a warning message in GitHub Actions .DESCRIPTION Write a warning message in GitHub Actions. The message will be displayed in the GitHub Actions log. .EXAMPLE Write-GitHubWarning -Message 'Hello, World!' Writes a warning message 'Hello, World!'. .NOTES [Enabling debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Scope = 'Function', Justification = 'Long doc links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Scope = 'Function', Justification = 'Intended for logging in Github Runners' )] [OutputType([void])] [Alias('Warning')] [CmdletBinding()] param ( # Message to write [Parameter(Mandatory)] [string] $Message, # The name of the file that this warning is related to [Parameter()] [string] $Name, # The line number that this warning is related to [Parameter()] [int] $Line, # The column number that this warning is related to [Parameter()] [int] $Column, # The end column number that this warning is related to [Parameter()] [int] $EndColumn, # The end line number that this warning is related to [Parameter()] [int] $EndLine, # The title of the warning [Parameter()] [string] $Title ) if ($env:GITHUB_ACTIONS -eq 'true') { Write-Host "::warning file=$Name,line=$Line,col=$Column,endColumn=$EndColumn,endLine=$EndLine,title=$Title::$Message" } else { Write-Warning $Message } } Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubWarning] - Done" #endregion - From [functions] - [public] - [Commands] - [Write-GitHubWarning] Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - Done" #endregion - From [functions] - [public] - [Commands] #region - From [functions] - [public] - [Config] Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - Processing folder" #region - From [functions] - [public] - [Config] - [Get-GitHubConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Get-GitHubConfig] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Get-GitHubConfig { <# .SYNOPSIS Get a GitHub module configuration. .DESCRIPTION Get a GitHub module configuration. .EXAMPLE Get-GitHubConfig -Name DefaultUser Get the DefaultUser value from the GitHub module configuration. #> [OutputType([void])] [CmdletBinding()] param ( # The name of the configuration to get. [Parameter()] [string] $Name ) begin { $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" } process { if (-not $Name) { return Get-Context -ID $script:Config.Name } Get-ContextSetting -Name $Name -ID $script:Config.Name } end { Write-Verbose "[$commandName] - End" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Get-GitHubConfig] - Done" #endregion - From [functions] - [public] - [Config] - [Get-GitHubConfig] #region - From [functions] - [public] - [Config] - [Remove-GitHubConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Remove-GitHubConfig] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Remove-GitHubConfig { <# .SYNOPSIS Remove a GitHub module configuration. .DESCRIPTION Remove a GitHub module configuration. .EXAMPLE Remove-GitHubConfig -Name DefaultUser Removes the 'DefaultUser' item in the GitHub module configuration. #> [CmdletBinding(SupportsShouldProcess)] param ( # Set the access token type. [Parameter()] [string] $Name ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" try { if ($PSCmdlet.ShouldProcess('ContextSetting', 'Remove')) { Remove-ContextSetting -Name $Name -ID $script:Config.Name } } catch { Write-Error $_ Write-Error (Get-PSCallStack | Format-Table | Out-String) throw 'Failed to connect to GitHub.' } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Remove-GitHubConfig] - Done" #endregion - From [functions] - [public] - [Config] - [Remove-GitHubConfig] #region - From [functions] - [public] - [Config] - [Set-GitHubConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Set-GitHubConfig] - Importing" #Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' } function Set-GitHubConfig { <# .SYNOPSIS Set a GitHub module configuration. .DESCRIPTION Set a GitHub module configuration. .EXAMPLE Set-GitHubConfig -Name DefaultUser -Value 'Octocat' Sets the value of DefaultUser to 'Octocat' in the GitHub module configuration. #> [CmdletBinding(SupportsShouldProcess)] param ( # Set the access token type. [Parameter()] [string] $Name, # Set the access token type. [Parameter()] [string] $Value ) if ($PSCmdlet.ShouldProcess('ContextSetting', 'Set')) { Set-ContextSetting -Name $Name -Value $Value -ID $script:Config.Name } } Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Set-GitHubConfig] - Done" #endregion - From [functions] - [public] - [Config] - [Set-GitHubConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - Done" #endregion - From [functions] - [public] - [Config] #region - From [functions] - [public] - [Emojis] Write-Verbose "[$scriptName] - [functions] - [public] - [Emojis] - Processing folder" #region - From [functions] - [public] - [Emojis] - [Get-GitHubEmoji] Write-Verbose "[$scriptName] - [functions] - [public] - [Emojis] - [Get-GitHubEmoji] - Importing" filter Get-GitHubEmoji { <# .SYNOPSIS Get emojis .DESCRIPTION Lists all the emojis available to use on GitHub. If you pass the `Destination` parameter, the emojis will be downloaded to the specified destination. .EXAMPLE Get-GitHubEmoji Gets all the emojis available to use on GitHub. .EXAMPLE Get-GitHubEmoji -Destination 'C:\Users\user\Documents\GitHub\Emojis' Downloads all the emojis available to use on GitHub to the specified destination. .NOTES [Get emojis](https://docs.github.com/rest/reference/emojis#get-emojis) #> [CmdletBinding()] param ( # The path to the directory where the emojis will be downloaded. [Parameter()] [string] $Destination ) $inputObject = @{ APIEndpoint = '/emojis' Method = 'GET' } $response = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.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] - [functions] - [public] - [Emojis] - [Get-GitHubEmoji] - Done" #endregion - From [functions] - [public] - [Emojis] - [Get-GitHubEmoji] Write-Verbose "[$scriptName] - [functions] - [public] - [Emojis] - Done" #endregion - From [functions] - [public] - [Emojis] #region - From [functions] - [public] - [Enterprise] Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - Processing folder" #region - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization] - Importing" function Get-GitHubEnterpriseInstallableOrganization { <# .SYNOPSIS Get enterprise-owned organizations that can have GitHub Apps installed .DESCRIPTION List of organizations owned by the enterprise on which the authenticated GitHub App installation may install other GitHub Apps. The authenticated GitHub App must be installed on the enterprise and be granted the Enterprise/enterprise_organization_installations (read) permission. .EXAMPLE Get-GitHubEnterpriseInstallableOrganization -Enterprise 'msx' #> [CmdletBinding()] param( # The enterprise slug or ID. [Parameter(Mandatory)] [string] $Enterprise ) $inputObject = @{ APIEndpoint = "/enterprises/$Enterprise/apps/installable_organizations" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization] - Done" #endregion - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization] #region - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization] - Importing" function Get-GitHubEnterpriseOrganization { <# .SYNOPSIS Get the list of organizations in a GitHub Enterprise instance. .DESCRIPTION Use this function to retrieve the list of organizations in a GitHub Enterprise instance. .EXAMPLE Get-GitHubEnterpriseOrganization -EnterpriseSlug 'msx' #> [CmdletBinding()] param( [Parameter(Mandatory)] [string] $EnterpriseSlug ) # Define GraphQL query $query = @" query(`$enterpriseSlug: String!, `$first: Int = 100, `$after: String) { enterprise(slug: `$enterpriseSlug) { organizations(first: `$first, after: `$after) { edges { node { name login } } pageInfo { hasNextPage endCursor } } } } "@ # Initialize pagination variables $variables = @{ 'enterpriseSlug' = $EnterpriseSlug 'first' = 100 'after' = $null } $allOrgs = @() # Loop through pages to retrieve all organizations do { $response = Invoke-GitHubGraphQLQuery -Query $query -Variables $variables # Check for errors if ($response.errors) { Write-Error "Error: $($response.errors[0].message)" break } # Extract organization names and add to the list foreach ($org in $response.data.enterprise.organizations.edges) { $allOrgs += $org.node.name } # Update pagination cursor $pageInfo = $response.data.enterprise.organizations.pageInfo $variables.after = $pageInfo.endCursor } while ($pageInfo.hasNextPage -eq $true) # Output the list of organization names $allOrgs | ForEach-Object { Write-Output $_ } } Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization] - Done" #endregion - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization] #region - From [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization] - Importing" function Install-GitHubAppOnEnterpriseOrganization { <# .SYNOPSIS Install an app on an Enterprise-owned organization .DESCRIPTION Installs the provided GitHub App on the specified organization owned by the enterprise. The authenticated GitHub App must be installed on the enterprise and be granted the Enterprise/organization_installations (write) permission. .EXAMPLE Install-GitHubAppOnEnterpriseOrganization -Enterprise 'msx' -Organization 'org' -ClientID '123456' #> [CmdletBinding()] param( # The enterprise slug or ID. [Parameter(Mandatory)] [string] $Enterprise, # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [string] $Organization, # The client ID of the GitHub App to install. [Parameter(Mandatory)] [string] $ClientID, # The repository selection for the GitHub App. Can be one of: # - all - all repositories that the authenticated GitHub App installation can access. # - selected - select specific repositories. [Parameter()] [ValidateSet('all', 'selected')] [string] $RepositorySelection = 'all', # The names of the repositories to which the installation will be granted access. [Parameter()] [string[]] $Repositories ) $body = @{ client_id = $ClientID repository_selection = $RepositorySelection repositories = $Repositories } $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ APIEndpoint = "/enterprises/$Enterprise/apps/organizations/$Organization/installations" Method = 'Post' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization] - Done" #endregion - From [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - Done" #endregion - From [functions] - [public] - [Enterprise] #region - From [functions] - [public] - [Git] Write-Verbose "[$scriptName] - [functions] - [public] - [Git] - Processing folder" #region - From [functions] - [public] - [Git] - [Get-GitHubGitConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Git] - [Get-GitHubGitConfig] - Importing" function Get-GitHubGitConfig { <# .SYNOPSIS Gets the global Git configuration. .DESCRIPTION Gets the global Git configuration. .EXAMPLE Get-GitHubGitConfig Gets the global Git configuration. #> [OutputType([pscustomobject])] [CmdletBinding()] param() $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" $gitExists = Get-Command -Name 'git' -ErrorAction SilentlyContinue if (-not $gitExists) { throw 'Git is not installed. Please install Git before running this command.' } git config --local --list | ForEach-Object { ( [pscustomobject]@{ Name = $_.Split('=')[0] Value = $_.Split('=')[1] } ) } Write-Verbose "[$commandName] - End" } Write-Verbose "[$scriptName] - [functions] - [public] - [Git] - [Get-GitHubGitConfig] - Done" #endregion - From [functions] - [public] - [Git] - [Get-GitHubGitConfig] #region - From [functions] - [public] - [Git] - [Set-GitHubGitConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Git] - [Set-GitHubGitConfig] - Importing" function Set-GitHubGitConfig { <# .SYNOPSIS Set the Git configuration for the GitHub context. .DESCRIPTION Sets the Git configuration for the GitHub context. This command sets the `user.name`, `user.email`, and `url.<host>.insteadOf` git configs. .EXAMPLE Set-GitHubGitConfig Sets the Git configuration for the default GitHub context. .EXAMPLE Set-GitHubGitConfig -Context 'MyContext' Sets the Git configuration for the GitHub context named 'MyContext'. #> [CmdletBinding(SupportsShouldProcess)] param ( # The context to use for the API call. This is used to retrieve the necessary configuration settings. [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $commandName = $MyInvocation.MyCommand.Name Write-Verbose "[$commandName] - Start" $gitExists = Get-Command -Name 'git' -ErrorAction SilentlyContinue if (-not $gitExists) { throw 'Git is not installed. Please install Git before running this command.' } $contextObj = Get-GitHubContext -Name $Context Write-Verbose "Using GitHub context: $Context" if (-not $contextObj) { throw 'Log in using Connect-GitHub before running this command.' } $username = $contextObj.UserName $id = $contextObj.DatabaseID $token = $contextObj.Token | ConvertFrom-SecureString -AsPlainText $hostName = $contextObj.HostName if ($PSCmdlet.ShouldProcess("$Name", 'Set Git configuration')) { git config --local user.name "$username" git config --local user.email "$id+$username@users.noreply.github.com" git config --local "url.https://oauth2:$token@$hostName.insteadOf" "https://$hostName" Write-Verbose "[$commandName] - End" } } Write-Verbose "[$scriptName] - [functions] - [public] - [Git] - [Set-GitHubGitConfig] - Done" #endregion - From [functions] - [public] - [Git] - [Set-GitHubGitConfig] Write-Verbose "[$scriptName] - [functions] - [public] - [Git] - Done" #endregion - From [functions] - [public] - [Git] #region - From [functions] - [public] - [Gitignore] Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - Processing folder" #region - From [functions] - [public] - [Gitignore] - [Get-GitHubGitignore] Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - [Get-GitHubGitignore] - Importing" #Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } filter Get-GitHubGitignore { <# .SYNOPSIS Get a gitignore template or list of all gitignore templates names .DESCRIPTION If no parameters are specified, the function will return a list of all gitignore templates names. If the Name parameter is specified, the function will return the gitignore template for the specified name. .EXAMPLE Get-GitHubGitignoreList Get all gitignore templates .EXAMPLE Get-GitHubGitignore -Name 'VisualStudio' Get a gitignore template for VisualStudio .NOTES [Get a gitignore template](https://docs.github.com/rest/gitignore/gitignore#get-a-gitignore-template) [Get all gitignore templates](https://docs.github.com/rest/gitignore/gitignore#get-all-gitignore-templates) #> [CmdletBinding(DefaultParameterSetName = 'List')] param () dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ Name = 'Name' ParameterSetName = 'Name' Type = [string] Mandatory = $true ValidateSet = Get-GitHubGitignoreList DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam return $DynamicParamDictionary } process { $Name = $PSBoundParameters['Name'] switch ($PSCmdlet.ParameterSetName) { 'List' { Get-GitHubGitignoreList } 'Name' { Get-GitHubGitignoreByName -Name $Name } } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - [Get-GitHubGitignore] - Done" #endregion - From [functions] - [public] - [Gitignore] - [Get-GitHubGitignore] Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - Done" #endregion - From [functions] - [public] - [Gitignore] #region - From [functions] - [public] - [GraphQL] Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - Processing folder" #region - From [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery] Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery] - Importing" function Invoke-GitHubGraphQLQuery { <# .SYNOPSIS Invoke a GraphQL query against the GitHub GraphQL API .DESCRIPTION Use this function to invoke a GraphQL query against the GitHub GraphQL API. .EXAMPLE Invoke-GitHubGraphQLQuery -Query $query -Variables $Variables .NOTES [GitHub GraphQL API documentation](https://docs.github.com/graphql) #> param ( # The GraphQL query to execute. [string] $Query, # The variables to pass to the query. [hashtable] $Variables, # The context to run the command in. [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $inputObject = @{ Context = $Context APIEndpoint = '/graphql' Method = 'Post' Body = @{ 'query' = $query 'variables' = $variables } | ConvertTo-Json } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery] - Done" #endregion - From [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery] Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - Done" #endregion - From [functions] - [public] - [GraphQL] #region - From [functions] - [public] - [License] Write-Verbose "[$scriptName] - [functions] - [public] - [License] - Processing folder" #region - From [functions] - [public] - [License] - [Get-GitHubLicense] Write-Verbose "[$scriptName] - [functions] - [public] - [License] - [Get-GitHubLicense] - Importing" #Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } filter Get-GitHubLicense { <# .SYNOPSIS Get a license template, list of all popular license templates or a license for a repository .DESCRIPTION If no parameters are specified, the function will return a list of all license templates. If the Name parameter is specified, the function will return the license template for the specified name. If the Owner and Repo parameters are specified, the function will return the license for the specified repository. .EXAMPLE Get-GitHubLicense Get all license templates .EXAMPLE Get-GitHubLicense -Name mit Get the mit license template .EXAMPLE Get-GitHubLicense -Owner 'octocat' -Repo 'Hello-World' Get the license for the Hello-World repository from the octocat account. .PARAMETER Name The license keyword, license name, or license SPDX ID. For example, mit or mpl-2.0. .NOTES [Get a license](https://docs.github.com/rest/licenses/licenses#get-a-license) [Get all commonly used licenses](https://docs.github.com/rest/licenses/licenses#get-all-commonly-used-licenses) [Get the license for a repository](https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository) #> [CmdletBinding(DefaultParameterSetName = 'List')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'Repository')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(ParameterSetName = 'Repository')] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ Name = 'Name' ParameterSetName = 'Name' Type = [string] Mandatory = $true ValidateSet = Get-GitHubLicenseList | Select-Object -ExpandProperty Name DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam return $DynamicParamDictionary } process { $Name = $PSBoundParameters['Name'] switch ($PSCmdlet.ParameterSetName) { 'List' { Get-GitHubLicenseList } 'Name' { Get-GitHubLicenseByName -Name $Name } 'Repository' { Get-GitHubRepositoryLicense -Owner $Owner -Repo $Repo } } } } Write-Verbose "[$scriptName] - [functions] - [public] - [License] - [Get-GitHubLicense] - Done" #endregion - From [functions] - [public] - [License] - [Get-GitHubLicense] Write-Verbose "[$scriptName] - [functions] - [public] - [License] - Done" #endregion - From [functions] - [public] - [License] #region - From [functions] - [public] - [Markdown] Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - Processing folder" #region - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdown] Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdown] - Importing" filter Get-GitHubMarkdown { <# .NOTES [Render a Markdown document](https://docs.github.com/en/rest/markdown/markdown#render-a-markdown-document) #> [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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdown] - Done" #endregion - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdown] #region - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw] Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw] - Importing" filter Get-GitHubMarkdownRaw { <# .NOTES [Render a Markdown document in raw mode](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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw] - Done" #endregion - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw] Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - Done" #endregion - From [functions] - [public] - [Markdown] #region - From [functions] - [public] - [Meta] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - Processing folder" #region - From [functions] - [public] - [Meta] - [Get-GitHubApiVersion] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubApiVersion] - Importing" filter Get-GitHubApiVersion { <# .SYNOPSIS Get all API versions. .DESCRIPTION Get all supported GitHub API versions. .EXAMPLE Get-GitHubApiVersion Get all supported GitHub API versions. .NOTES [Get all API versions](https://docs.github.com/rest/meta/meta#get-all-api-versions) #> [OutputType([string[]])] [CmdletBinding()] param () $inputObject = @{ ApiEndpoint = '/versions' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubApiVersion] - Done" #endregion - From [functions] - [public] - [Meta] - [Get-GitHubApiVersion] #region - From [functions] - [public] - [Meta] - [Get-GitHubMeta] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubMeta] - 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 [Get GitHub meta information](https://docs.github.com/rest/meta/meta#get-apiname-meta-information) #> [OutputType([object])] [CmdletBinding()] param () $inputObject = @{ ApiEndpoint = '/meta' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubMeta] - Done" #endregion - From [functions] - [public] - [Meta] - [Get-GitHubMeta] #region - From [functions] - [public] - [Meta] - [Get-GitHubOctocat] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubOctocat] - 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 [Get Octocat](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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubOctocat] - Done" #endregion - From [functions] - [public] - [Meta] - [Get-GitHubOctocat] #region - From [functions] - [public] - [Meta] - [Get-GitHubRoot] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubRoot] - 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 [GitHub API Root](https://docs.github.com/rest/meta/meta#github-api-root) #> [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubRoot] - Done" #endregion - From [functions] - [public] - [Meta] - [Get-GitHubRoot] #region - From [functions] - [public] - [Meta] - [Get-GitHubZen] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubZen] - 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 [Get the Zen of GitHub](https://docs.github.com/rest/meta/meta#get-the-zen-of-github) #> [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/zen' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubZen] - Done" #endregion - From [functions] - [public] - [Meta] - [Get-GitHubZen] Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - Done" #endregion - From [functions] - [public] - [Meta] #region - From [functions] - [public] - [Organization] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - Processing folder" #region - From [functions] - [public] - [Organization] - [Members] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - Processing folder" #region - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember] - Importing" function Get-GitHubOrganizationMember { <# .SYNOPSIS List organization members .DESCRIPTION List all users who are members of an organization. If the authenticated user is also a member of this organization then both concealed and public members will be returned. .NOTES [List organization members](https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28#list-organization-members) #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # Filter members returned in the list. # `2fa_disabled` means that only members without two-factor authentication enabled will be returned. # This options is only available for organization owners. [Parameter()] [ValidateSet('2fa_disabled', 'all')] [string] $Filter = 'all', # Filter members returned by their role. [Parameter()] [ValidateSet('all', 'admin', 'member')] [string] $Role = 'all', # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $body = @{ filter = $Filter role = $Role per_page = $PerPage } $inputObject = @{ Context = $Context Body = $body Method = 'Get' APIEndpoint = "/orgs/$Organization/members" } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember] - Done" #endregion - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember] #region - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation] - Importing" function Get-GitHubOrganizationPendingInvitation { <# .SYNOPSIS List pending organization invitations .DESCRIPTION The return hash contains a `role` field which refers to the Organization Invitation role and will be one of the following values: `direct_member`, `admin`, `billing_manager`, or `hiring_manager`. If the invitee is not a GitHub member, the `login` field in the return hash will be `null`. .NOTES [List pending organization invitations](https://docs.github.com/rest/orgs/members#list-pending-organization-invitations) #> [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # Filter invitations by their member role. [Parameter()] [ValidateSet('all', 'admin', 'direct_member', 'billing_manager', 'hiring_manager')] [string] $Role = 'all', # Filter invitations by their invitation source. [Parameter()] [ValidateSet('all', 'member', 'scim')] [string] $InvitationSource = 'all', # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $body = @{ role = $Role invitation_source = $InvitationSource per_page = $PerPage } $inputObject = @{ Context = $Context Body = $body Method = 'Get' APIEndpoint = "/orgs/$Organization/invitations" } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation] - Done" #endregion - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation] #region - From [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation] - Importing" function New-GitHubOrganizationInvitation { <# .SYNOPSIS Create an organization invitation .DESCRIPTION Invite people to an organization by using their GitHub user ID or their email address. In order to create invitations in an organization, the authenticated user must be an organization owner. This endpoint triggers [notifications](https://docs.github.com/github/managing-subscriptions-and-notifications-on-github/about-notifications). Creating content too quickly using this endpoint may result in secondary rate limiting. For more information, see "[Rate limits for the API](https://docs.github.com/rest/using-the-rest-api/rate-limits-for-the-rest-api#about-secondary-rate-limits)" and "[Best practices for using the REST API](https://docs.github.com/rest/guides/best-practices-for-using-the-rest-api)." .NOTES [Create an organization invitation](https://docs.github.com/rest/orgs/members#list-pending-organization-invitations) #> [CmdletBinding(SupportsShouldProcess)] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # GitHub user ID for the person you are inviting. [Parameter( Mandatory, ParameterSetName = 'UserID' )] [Alias('invitee_id', 'user_id')] [int] $InviteeID, # Email address of the person you are inviting, which can be an existing GitHub user. [Parameter( Mandatory, ParameterSetName = 'Email' )] [string] $Email, # The role for the new member. # # - `admin` - Organization owners with full administrative rights to the organization and complete access to all repositories and teams. # - `direct_member` - Non-owner organization members with ability to see other members and join teams by invitation. # - `billing_manager` - Non-owner organization members with ability to manage the billing settings of your organization. # - `reinstate` - The previous role assigned to the invitee before they were removed from your organization. # Can be one of the roles listed above. # Only works if the invitee was previously part of your organization. [Parameter()] [ValidateSet('admin', 'direct_member', 'billing_manager', 'reinstate')] [string] $Role = 'direct_member', # Specify IDs for the teams you want to invite new members to. [Parameter()] [int[]] $TeamIDs, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name 'DefaultContext') ) $body = @{ invitee_id = $InviteeID email = $Email role = $Role team_ids = $TeamIDs } $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ Context = $Context Body = $body Method = 'post' APIEndpoint = "/orgs/$Organization/invitations" } if ($PSCmdlet.ShouldProcess("$InviteeID$Email to organization $Organization", 'Invite')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation] - Done" #endregion - From [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - Done" #endregion - From [functions] - [public] - [Organization] - [Members] #region - From [functions] - [public] - [Organization] - [Get-GitHubOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Get-GitHubOrganization] - 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 [List organizations](https://docs.github.com/rest/orgs/orgs) #> [OutputType([pscustomobject])] [CmdletBinding(DefaultParameterSetName = '__DefaultSet')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'All', Justification = 'Required for parameter set')] 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')] [ValidateRange(1, 100)] [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] - [functions] - [public] - [Organization] - [Get-GitHubOrganization] - Done" #endregion - From [functions] - [public] - [Organization] - [Get-GitHubOrganization] #region - From [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation] - 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 [List app installations for an organization](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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = @{ per_page = $PerPage } $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName/installations" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response.installations } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation] - Done" #endregion - From [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation] #region - From [functions] - [public] - [Organization] - [Remove-GitHubOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Remove-GitHubOrganization] - 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 [GitHub Terms of Service](https://docs.github.com/site-policy/github-terms/github-terms-of-service) regarding account deletion before using this endpoint. .EXAMPLE Remove-GitHubOrganization -OrganizationName 'GitHub' Deletes the organization 'GitHub' and all its repositories. .NOTES [Delete an organization](https://docs.github.com/rest/orgs/orgs#delete-an-organization) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] 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' } if ($PSCmdlet.ShouldProcess("organization [$OrganizationName]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Remove-GitHubOrganization] - Done" #endregion - From [functions] - [public] - [Organization] - [Remove-GitHubOrganization] #region - From [functions] - [public] - [Organization] - [Set-GitHubOrganization] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganization] - 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 [Update an organization](https://docs.github.com/rest/orgs/orgs#update-an-organization) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] 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-HashtableEntry -Hashtable $body -RemoveNames 'organization_name' $inputObject = @{ APIEndpoint = "/orgs/$OrganizationName" Method = 'PATCH' Body = $body } if ($PSCmdlet.ShouldProcess("organization [$OrganizationName]", 'Set')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganization] - Done" #endregion - From [functions] - [public] - [Organization] - [Set-GitHubOrganization] #region - From [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature] - 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 [Enable or disable a security feature for an organization](https://docs.github.com/rest/orgs/orgs#enable-or-disable-a-security-feature-for-an-organization) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long link in notes.')] [CmdletBinding(SupportsShouldProcess)] 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 } if ($PSCmdlet.ShouldProcess("security feature [$SecurityProduct] on organization [$OrganizationName]", 'Set')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature] - Done" #endregion - From [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature] Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - Done" #endregion - From [functions] - [public] - [Organization] #region - From [functions] - [public] - [Rate-Limit] Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - Processing folder" #region - From [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit] Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit] - Importing" filter Get-GitHubRateLimit { <# .SYNOPSIS Get rate limit status for the authenticated user .DESCRIPTION **Note:** Accessing this endpoint does not count against your REST API rate limit. Some categories of endpoints have custom rate limits that are separate from the rate limit governing the other REST API endpoints. For this reason, the API response categorizes your rate limit. Under `resources`, you'll see objects relating to different categories: * The `core` object provides your rate limit status for all non-search-related resources in the REST API. * The `search` object provides your rate limit status for the REST API for searching (excluding code searches). For more information, see "[Search](https://docs.github.com/rest/search)." * The `code_search` object provides your rate limit status for the REST API for searching code. For more information, see "[Search code](https://docs.github.com/rest/search/search#search-code)." * The `graphql` object provides your rate limit status for the GraphQL API. For more information, see "[Resource limitations](https://docs.github.com/graphql/overview/resource-limitations#rate-limit)." * The `integration_manifest` object provides your rate limit status for the `POST /app-manifests/{code}/conversions` operation. For more information, see "[Creating a GitHub App from a manifest](https://docs.github.com/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app-from-a-manifest#3-you-exchange-the-temporary-code-to-retrieve-the-app-configuration)." * The `dependency_snapshots` object provides your rate limit status for submitting snapshots to the dependency graph. For more information, see "[Dependency graph](https://docs.github.com/rest/dependency-graph)." * The `code_scanning_upload` object provides your rate limit status for uploading SARIF results to code scanning. For more information, see "[Uploading a SARIF file to GitHub](https://docs.github.com/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github)." * The `actions_runner_registration` object provides your rate limit status for registering self-hosted runners in GitHub Actions. For more information, see "[Self-hosted runners](https://docs.github.com/rest/actions/self-hosted-runners)." * The `source_import` object is no longer in use for any API endpoints, and it will be removed in the next API version. For more information about API versions, see "[API Versions](https://docs.github.com/rest/overview/api-versions)." **Note:** The `rate` object is deprecated. If you're writing new API client code or updating existing code, you should use the `core` object instead of the `rate` object. The `core` object contains the same information that is present in the `rate` object. .EXAMPLE Get-GitHubRateLimit Gets the rate limit status for the authenticated user. .NOTES [Get rate limit status for the authenticated user](https://docs.github.com/rest/rate-limit/rate-limit#get-rate-limit-status-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding()] param () $inputObject = @{ APIEndpoint = '/rate_limit' Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response.Resources } } Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit] - Done" #endregion - From [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit] Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - Done" #endregion - From [functions] - [public] - [Rate-Limit] #region - From [functions] - [public] - [Releases] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - Processing folder" #region - From [functions] - [public] - [Releases] - [Assets] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - Processing folder" #region - From [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset] - Importing" filter Add-GitHubReleaseAsset { <# .SYNOPSIS Upload a release asset .DESCRIPTION This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in the response of the [Create a release endpoint](https://docs.github.com/rest/releases/releases#create-a-release) to upload a release asset. You need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint. Most libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: `application/zip` GitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example, you'll still need to pass your authentication to be able to upload an asset. When an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted. **Notes:** * GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The "[List release assets](https://docs.github.com/rest/releases/assets#list-release-assets)" endpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://support.github.com/contact?tags=dotcom-rest-api). * To find the `release_id` query the [`GET /repos/{owner}/{repo}/releases/latest` endpoint](https://docs.github.com/rest/releases/releases#get-the-latest-release). * If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset. .EXAMPLE Add-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '7654321' -FilePath 'C:\Users\octocat\Downloads\hello-world.zip' Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'. .NOTES [Upload a release asset](https://docs.github.com/rest/releases/assets#upload-a-release-asset) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the release. [Parameter(Mandatory)] [Alias('release_id')] [string] $ID, #The name of the file asset. [Parameter()] [string] $Name, # An alternate short description of the asset. Used in place of the filename. [Parameter()] [string] $Label, # The content type of the asset. [Parameter()] [string] $ContentType, # The path to the asset file. [Parameter(Mandatory)] [alias('fullname')] [string] $FilePath ) # If name is not provided, use the name of the file if (!$Name) { $Name = (Get-Item $FilePath).Name } # If label is not provided, use the name of the file if (!$Label) { $Label = (Get-Item $FilePath).Name } # If content type is not provided, use the file extension if (!$ContentType) { $ContentType = switch ((Get-Item $FilePath).Extension) { '.zip' { 'application/zip' } '.tar' { 'application/x-tar' } '.gz' { 'application/gzip' } '.bz2' { 'application/x-bzip2' } '.xz' { 'application/x-xz' } '.7z' { 'application/x-7z-compressed' } '.rar' { 'application/vnd.rar' } '.tar.gz' { 'application/gzip' } '.tgz' { 'application/gzip' } '.tar.bz2' { 'application/x-bzip2' } '.tar.xz' { 'application/x-xz' } '.tar.7z' { 'application/x-7z-compressed' } '.tar.rar' { 'application/vnd.rar' } '.png' { 'image/png' } '.json' { 'application/json' } '.txt' { 'text/plain' } '.md' { 'text/markdown' } '.html' { 'text/html' } default { 'application/octet-stream' } } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID', 'FilePath' $body['name'] = $Name $body['label'] = $Label Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues $release = Get-GitHubRelease -Owner $Owner -Repo $Repo -ID $ID $uploadURI = $release.upload_url -replace '{\?name,label}', "?name=$($Name)&label=$($Label)" $inputObject = @{ URI = $uploadURI Method = 'POST' ContentType = $ContentType UploadFilePath = $FilePath } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset] - Done" #endregion - From [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset] #region - From [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset] - Importing" filter Get-GitHubReleaseAsset { <# .SYNOPSIS List release assets based on a release ID or asset ID .DESCRIPTION If an asset ID is provided, the asset is returned. If a release ID is provided, all assets for the release are returned. .EXAMPLE Get-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'. .EXAMPLE Get-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ReleaseID '7654321' Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'. .NOTES [Get a release asset](https://docs.github.com/rest/releases/assets#get-a-release-asset) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the asset. [Parameter( Mandatory, ParameterSetName = 'ID' )] [Alias('asset_id')] [string] $ID, # The unique identifier of the release. [Parameter( Mandatory, ParameterSetName = 'ReleaseID' )] [Alias('release_id')] [string] $ReleaseID ) if ($ReleaseID) { Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repo $Repo -ReleaseID $ReleaseID } if ($ID) { Get-GitHubReleaseAssetByID -Owner $Owner -Repo $Repo -ID $ID } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset] - Done" #endregion - From [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset] #region - From [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset] - Importing" filter Remove-GitHubReleaseAsset { <# .SYNOPSIS Delete a release asset .DESCRIPTION Delete a release asset .EXAMPLE Remove-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Deletes the release asset with the ID '1234567' for the repository 'octocat/hello-world'. .NOTES [Delete a release asset](https://docs.github.com/rest/releases/assets#delete-a-release-asset) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the asset. [Parameter(Mandatory)] [Alias('asset_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("Asset with ID [$ID] in [$Owner/$Repo]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset] - Done" #endregion - From [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset] #region - From [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset] - Importing" filter Set-GitHubReleaseAsset { <# .SYNOPSIS Update a release asset .DESCRIPTION Users with push access to the repository can edit a release asset. .EXAMPLE Set-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567' -Name 'new_asset_name' -Label 'new_asset_label' Updates the release asset with the ID '1234567' for the repository 'octocat/hello-world' with the new name 'new_asset_name' and label 'new_asset_label'. .NOTES [Update a release asset](https://docs.github.com/rest/releases/assets#update-a-release-asset) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the asset. [Parameter(Mandatory)] [Alias('asset_id')] [string] $ID, #The name of the file asset. [Parameter()] [string] $Name, # An alternate short description of the asset. Used in place of the filename. [Parameter()] [string] $Label, # State of the release asset. [Parameter()] [ValidateSet('uploaded', 'open')] [string] $State ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID" Method = 'PATCH' Body = $requestBody } if ($PSCmdlet.ShouldProcess("assets for release with ID [$ID] in [$Owner/$Repo]", 'Set')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset] - Done" #endregion - From [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - Done" #endregion - From [functions] - [public] - [Releases] - [Assets] #region - From [functions] - [public] - [Releases] - [Releases] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - Processing folder" #region - From [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease] - Importing" filter Get-GitHubRelease { <# .SYNOPSIS List releases .DESCRIPTION This returns a list of releases, which does not include regular Git tags that have not been associated with a release. To get a list of Git tags, use the [Repository Tags API](https://docs.github.com/rest/repos/repos#list-repository-tags). Information about published releases are available to everyone. Only users with push access will receive listings for draft releases. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' Gets the releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -Latest Gets the latest releases for the repository 'hello-world' owned by 'octocat'. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -Tag 'v1.0.0' Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'. .EXAMPLE Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Gets the release with the ID '1234567' for the repository 'hello-world' owned by 'octocat'. .NOTES [List releases](https://docs.github.com/rest/releases/releases#list-releases) [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release) #> [CmdletBinding(DefaultParameterSetName = 'All')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Latest', Justification = 'Required for parameter set')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter(ParameterSetName = 'All')] [ValidateRange(1, 100)] [int] $PerPage = 30, # Get the latest release only [Parameter( Mandatory, ParameterSetName = 'Latest' )] [switch] $Latest, # The name of the tag to get a release from. [Parameter( Mandatory, ParameterSetName = 'Tag' )] [Alias('tag_name')] [string] $Tag, # The unique identifier of the release. [Parameter( Mandatory, ParameterSetName = 'ID' )] [Alias('release_id')] [string] $ID ) switch ($PSCmdlet.ParameterSetName) { 'All' { Get-GitHubReleaseAll -Owner $Owner -Repo $Repo -PerPage $PerPage } 'Latest' { Get-GitHubReleaseLatest -Owner $Owner -Repo $Repo } 'Tag' { Get-GitHubReleaseByTagName -Owner $Owner -Repo $Repo -Tag $Tag } 'ID' { Get-GitHubReleaseByID -Owner $Owner -Repo $Repo -ID $ID } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease] - Done" #endregion - From [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease] #region - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease] - Importing" filter New-GitHubRelease { <# .SYNOPSIS Create a release .DESCRIPTION Users with push access to the repository can create a release. This endpoint triggers [notifications](https://docs.github.com/github/managing-subscriptions-and-notifications-on-github/about-notifications). Creating content too quickly using this endpoint may result in secondary rate limiting. See "[Secondary rate limits](https://docs.github.com/rest/overview/resources-in-the-rest-api#secondary-rate-limits)" and "[Dealing with secondary rate limits](https://docs.github.com/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits)" for details. .EXAMPLE New-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -TagName 'v1.0.0' -TargetCommitish 'main' -Body 'Release notes' Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'. .NOTES [Create a release](https://docs.github.com/rest/releases/releases#create-a-release) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The name of the tag. [Parameter(Mandatory)] [Alias('tag_name')] [string] $TagName, # Specifies the commitish value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] [Alias('target_commitish')] [string] $TargetCommitish = 'main', # The name of the release. [Parameter()] [string] $Name, # Text describing the contents of the tag. [Parameter()] [string] $Body, # Whether the release is a draft. [Parameter()] [switch] $Draft, # Whether to identify the release as a prerelease. [Parameter()] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. # The value must be a category that already exists in the repository. # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). [Parameter()] [Alias('discussion_category_name')] [string] $DiscussionCategoryName, # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise,a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. [Parameter()] [Alias('generate_release_notes')] [switch] $GenerateReleaseNotes, # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation date and higher semantic version. [Parameter()] [Alias('make_latest')] [ValidateSet('true', 'false', 'legacy')] [string] $MakeLatest = 'true' ) $requestBody = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $requestBody -RemoveNames 'Owner', 'Repo', 'GenerateReleaseNotes', 'Draft', 'Prerelease' $requestBody = Join-Object -AsHashtable -Main $requestBody -Overrides @{ generate_release_notes = $GenerateReleaseNotes.IsPresent draft = $Draft.IsPresent prerelease = $Prerelease.IsPresent } Remove-HashtableEntry -Hashtable $requestBody -NullOrEmptyValues $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases" Method = 'POST' Body = $requestBody } if ($PSCmdlet.ShouldProcess("$Owner/$Repo", 'Create a release')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease] - Done" #endregion - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease] #region - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote] - Importing" filter New-GitHubReleaseNote { <# .SYNOPSIS List releases .DESCRIPTION Generate a name and body describing a [release](https://docs.github.com/en/rest/releases/releases#get-a-release). The body content will be Markdown formatted and contain information like the changes since last release and users who contributed. The generated release notes are not saved anywhere. They are intended to be generated and used when creating a new release. .EXAMPLE $params = @{ Owner = 'octocat' Repo = 'hello-world' TagName = 'v1.0.0' } New-GitHubReleaseNote @params Creates a new release notes draft for the repository 'hello-world' owned by 'octocat' with the tag name 'v1.0.0'. In this example the tag 'v1.0.0' has to exist in the repository. The configuration file '.github/release.yml' or '.github/release.yaml' will be used. .EXAMPLE $params = @{ Owner = 'octocat' Repo = 'hello-world' TagName = 'v1.0.0' TargetCommitish = 'main' } New-GitHubReleaseNote @params Creates a new release notes draft for the repository 'hello-world' owned by 'octocat' with the tag name 'v1.0.0'. In this example the tag 'v1.0.0' has to exist in the repository. .EXAMPLE $params = @{ Owner = 'octocat' Repo = 'hello-world' TagName = 'v1.0.0' TargetCommitish = 'main' PreviousTagName = 'v0.9.2' ConfigurationFilePath = '.github/custom_release_config.yml' } New-GitHubReleaseNote @params Creates a new release notes draft for the repository 'hello-world' owned by 'octocat' with the tag name 'v1.0.0'. The release notes will be based on the changes between the tags 'v0.9.2' and 'v1.0.0' and generated based on the configuration file located in the repository at '.github/custom_release_config.yml'. .NOTES [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#list-releases) #> [OutputType([pscustomobject])] [Alias('Generate-GitHubReleaseNotes')] [Alias('New-GitHubReleaseNotes')] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The tag name for the release. This can be an existing tag or a new one. [Parameter(Mandatory)] [Alias('tag_name')] [string] $TagName, # Specifies the commitish value that will be the target for the release's tag. # Required if the supplied tag_name does not reference an existing tag. # Ignored if the tag_name already exists. [Parameter()] [Alias('target_commitish')] [string] $TargetCommitish, # The name of the previous tag to use as the starting point for the release notes. # Use to manually specify the range for the set of changes considered as part this release. [Parameter()] [Alias('previous_tag_name')] [string] $PreviousTagName, # Specifies a path to a file in the repository containing configuration settings used for generating the release notes. # If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used. # If that is not present, the default configuration will be used. [Parameter()] [Alias('configuration_file_path')] [string] $ConfigurationFilePath ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/generate-notes" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("$Owner/$Repo", 'Create release notes')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote] - Done" #endregion - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote] #region - From [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease] - Importing" filter Remove-GitHubRelease { <# .SYNOPSIS Delete a release .DESCRIPTION Users with push access to the repository can delete a release. .EXAMPLE Remove-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -ID '1234567' Deletes the release with the ID '1234567' for the repository 'octocat/hello-world'. .NOTES [Delete a release](https://docs.github.com/rest/releases/releases#delete-a-release) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the release. [Parameter( Mandatory )] [Alias('release_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/$ID" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repo]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease] - Done" #endregion - From [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease] #region - From [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease] - Importing" filter Set-GitHubRelease { <# .SYNOPSIS Update a release .DESCRIPTION Users with push access to the repository can edit a release. .EXAMPLE Set-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -ID '1234567' -Body 'Release notes' Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the body 'Release notes'. .NOTES [Update a release](https://docs.github.com/rest/releases/releases#update-a-release) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the release. [Parameter(Mandatory)] [Alias('release_id')] [string] $ID, # The name of the tag. [Parameter()] [Alias('tag_name')] [string] $TagName, # Specifies the commitish value that determines where the Git tag is created from. # Can be any branch or commit SHA. Unused if the Git tag already exists. # API Default: the repository's default branch. [Parameter()] [Alias('target_commitish')] [string] $TargetCommitish, # The name of the release. [Parameter()] [string] $Name, # Text describing the contents of the tag. [Parameter()] [string] $Body, # Whether the release is a draft. [Parameter()] [switch] $Draft, # Whether to identify the release as a prerelease. [Parameter()] [switch] $Prerelease, # If specified, a discussion of the specified category is created and linked to the release. # The value must be a category that already exists in the repository. # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository). [Parameter()] [Alias('discussion_category_name')] [string] $DiscussionCategoryName, # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. # Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation # date and higher semantic version. [Parameter()] [Alias('make_latest')] [ValidateSet('true', 'false', 'legacy')] [string] $MakeLatest = 'true' ) $requestBody = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $requestBody -RemoveNames 'Owner', 'Repo', 'Draft', 'Prerelease' $requestBody = Join-Object -AsHashtable -Main $requestBody -Overrides @{ draft = if ($Draft.IsPresent) { $Draft } else { $false } prerelease = if ($Prerelease.IsPresent) { $Prerelease } else { $false } } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/releases/$ID" Method = 'PATCH' Body = $requestBody } if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repo]", 'Update')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease] - Done" #endregion - From [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - Done" #endregion - From [functions] - [public] - [Releases] - [Releases] Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - Done" #endregion - From [functions] - [public] - [Releases] #region - From [functions] - [public] - [Repositories] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - Processing folder" #region - From [functions] - [public] - [Repositories] - [Autolinks] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - Processing folder" #region - From [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink] - Importing" filter Get-GitHubRepositoryAutolink { <# .SYNOPSIS List all autolinks of a repository .DESCRIPTION This returns a list of autolinks configured for the given repository. Information about autolinks are only available to repository administrators. .EXAMPLE Get-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' Gets all autolinks for the repository 'Hello-World' owned by 'octocat'. .EXAMPLE Get-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' -ID 1 Gets the autolink with the ID 1 for the repository 'Hello-World' owned by 'octocat'. .NOTES [Get all autolinks of a repository](https://docs.github.com/rest/repos/autolinks#list-all-autolinks-of-a-repository) #> [Alias('Get-GitHubRepositoryAutolinks')] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the autolink. [Parameter( Mandatory, ParameterSetName = 'ById' )] [Alias('autolink_id')] [Alias('ID')] [int] $AutolinkId ) switch ($PSCmdlet.ParameterSetName) { 'ById' { Get-GitHubRepositoryAutolinkById -Owner $Owner -Repo $Repo -ID $AutolinkId } default { Get-GitHubRepositoryAutolinkList -Owner $Owner -Repo $Repo } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink] - Done" #endregion - From [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink] #region - From [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink] - Importing" filter New-GitHubRepositoryAutolink { <# .SYNOPSIS Create an autolink reference for a repository .DESCRIPTION Users with admin access to the repository can create an autolink. .EXAMPLE New-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' -KeyPrefix 'GH-' -UrlTemplate 'https://www.example.com/issue/<num>' Creates an autolink for the repository 'Hello-World' owned by 'octocat' that links to <https://www.example.com/issue/123> when the prefix 'GH-' is found in an issue, pull request, or commit. .NOTES [Create an autolink reference for a repository](https://docs.github.com/rest/repos/autolinks#create-an-autolink-reference-for-a-repository) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] [string] $Repo, # This prefix appended by certain characters will generate a link any time it is found in an issue, pull request, or commit. [Parameter(Mandatory)] [Alias('key_prefix')] [string] $KeyPrefix, # The URL must contain <num> for the reference number. <num> matches different characters depending on the value of is_alphanumeric. [Parameter(Mandatory)] [Alias('url_template')] [string] $UrlTemplate, # Whether this autolink reference matches alphanumeric characters. If true, the <num> parameter of the url_template matches alphanumeric # characters A-Z (case insensitive), 0-9, and -. If false, this autolink reference only matches numeric characters. [Parameter()] [Alias('is_alphanumeric')] [bool] $IsAlphanumeric = $true ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/autolinks" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("Autolink for repository [$Owner/$Repo]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink] - Done" #endregion - From [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink] #region - From [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink] - Importing" filter Remove-GitHubRepositoryAutolink { <# .SYNOPSIS Delete an autolink reference from a repository .DESCRIPTION This deletes a single autolink reference by ID that was configured for the given repository. Information about autolinks are only available to repository administrators. .EXAMPLE Remove-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' -AutolinkId 1 Deletes the autolink with ID 1 for the repository 'Hello-World' owned by 'octocat'. .NOTES [Delete an autolink reference from a repository](https://docs.github.com/rest/repos/autolinks#delete-an-autolink-reference-from-a-repository) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] [string] $Repo, # The unique identifier of the autolink. [Parameter(Mandatory)] [Alias('autolink_id')] [Alias('ID')] [int] $AutolinkId ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/autolinks/$AutolinkId" Method = 'DELETE' Body = $body } if ($PSCmdlet.ShouldProcess("Autolink with ID [$AutolinkId] for repository [$Owner/$Repo]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink] - Done" #endregion - From [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - Done" #endregion - From [functions] - [public] - [Repositories] - [Autolinks] #region - From [functions] - [public] - [Repositories] - [CustomProperties] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - Processing folder" #region - From [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty] - Importing" filter Get-GitHubRepositoryCustomProperty { <# .SYNOPSIS Get all custom property values for a repository .DESCRIPTION Gets all custom property values that are set for a repository. Users with read access to the repository can use this endpoint. .EXAMPLE Get-GitHubRepositoryCustomProperty -Owner 'octocat' -Repo 'hello-world' Gets all custom property values that are set for the 'hello-world' repository. .NOTES [Get all custom property values for a repository](https://docs.github.com/rest/repos/custom-properties#get-all-custom-property-values-for-a-repository) #> [Alias('Get-GitHubRepositoryCustomProperties')] [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [OutputType([pscustomobject])] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/properties/values" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty] - Done" #endregion - From [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - Done" #endregion - From [functions] - [public] - [Repositories] - [CustomProperties] #region - From [functions] - [public] - [Repositories] - [Repositories] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - Processing folder" #region - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting] - Importing" filter Disable-GitHubRepositoryPrivateVulnerabilityReporting { <# .SYNOPSIS Disable private vulnerability reporting for a repository .DESCRIPTION Disables private vulnerability reporting for a repository. The authenticated user must have admin access to the repository. For more information, see "[Privately reporting a security vulnerability](https://docs.github.com/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability)". .EXAMPLE Disable-GitHubRepositoryPrivateVulnerabilityReporting -Owner 'PSModule' -Repo 'GitHub' Disables private vulnerability reporting for the PSModule/GitHub repository. .NOTES [Disable private vulnerability reporting for a repository](https://docs.github.com/rest/repos/repos#disable-private-vulnerability-reporting-for-a-repository) #> [CmdletBinding(SupportsShouldProcess)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/private-vulnerability-reporting" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("Private Vulnerability Reporting for [$Owner/$Repo]", 'Disable')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix] - Importing" filter Disable-GitHubRepositorySecurityFix { <# .SYNOPSIS Disable automated security fixes .DESCRIPTION Disables automated security fixes for a repository. The authenticated user must have admin access to the repository. For more information, see "[Configuring automated security fixes](https://docs.github.com/articles/configuring-automated-security-fixes)". .EXAMPLE Disable-GitHubRepositorySecurityFix -Owner 'PSModule' -Repo 'GitHub' Disables automated security fixes for the repository. .NOTES [Disable automated security fixes](https://docs.github.com/rest/repos/repos#disable-automated-security-fixes) #> [CmdletBinding(SupportsShouldProcess)] [Alias('Disable-GitHubRepositorySecurityFixes')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/automated-security-fixes" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("Security Fixes for [$Owner/$Repo]", 'Disable')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert] - Importing" filter Disable-GitHubRepositoryVulnerabilityAlert { <# .SYNOPSIS Disable vulnerability alerts .DESCRIPTION Disables dependency alerts and the dependency graph for a repository. The authenticated user must have admin access to the repository. For more information, see "[About security alerts for vulnerable dependencies](https://docs.github.com/articles/about-security-alerts-for-vulnerable-dependencies)". .EXAMPLE Disable-GitHubRepositoryVulnerabilityAlert -Owner 'octocat' -Repo 'hello-world' Disables vulnerability alerts for the 'octocat/hello-world' repository. .NOTES [Disable vulnerability alerts](https://docs.github.com/rest/repos/repos#disable-vulnerability-alerts) #> [CmdletBinding(SupportsShouldProcess)] [Alias('Disable-GitHubRepositoryVulnerabilityAlerts')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/vulnerability-alerts" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("Vulnerability Alerts for [$Owner/$Repo]", 'Disable')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting] - Importing" filter Enable-GitHubRepositoryPrivateVulnerabilityReporting { <# .SYNOPSIS Enable private vulnerability reporting for a repository .DESCRIPTION Enables private vulnerability reporting for a repository. The authenticated user must have admin access to the repository. For more information, see "[Privately reporting a security vulnerability](https://docs.github.com/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability)." .EXAMPLE Enable-GitHubRepositoryPrivateVulnerabilityReporting -Owner 'PSModule' -Repo 'GitHub' Enables private vulnerability reporting for the PSModule/GitHub repository. .NOTES [Enable private vulnerability reporting for a repository](https://docs.github.com/rest/repos/repos#enable-private-vulnerability-reporting-for-a-repository) #> [CmdletBinding(SupportsShouldProcess)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/private-vulnerability-reporting" Method = 'PUT' } if ($PSCmdlet.ShouldProcess("Private Vulnerability Reporting for [$Owner/$Repo]", 'Enable')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix] - Importing" filter Enable-GitHubRepositorySecurityFix { <# .SYNOPSIS Enable automated security fixes .DESCRIPTION Enables automated security fixes for a repository. The authenticated user must have admin access to the repository. For more information, see "[Configuring automated security fixes](https://docs.github.com/articles/configuring-automated-security-fixes)". .EXAMPLE Enable-GitHubRepositorySecurityFix -Owner 'PSModule' -Repo 'GitHub' Enables automated security fixes for the repository. .NOTES [Enable automated security fixes](https://docs.github.com/rest/repos/repos#enable-automated-security-fixes) #> [CmdletBinding(SupportsShouldProcess)] [Alias('Enable-GitHubRepositorySecurityFixes')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/automated-security-fixes" Method = 'PUT' } if ($PSCmdlet.ShouldProcess("Security Fixes for [$Owner/$Repo]", 'Enable')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert] - Importing" filter Enable-GitHubRepositoryVulnerabilityAlert { <# .SYNOPSIS Enable vulnerability alerts .DESCRIPTION Enables dependency alerts and the dependency graph for a repository. The authenticated user must have admin access to the repository. For more information, see "[About security alerts for vulnerable dependencies](https://docs.github.com/articles/about-security-alerts-for-vulnerable-dependencies)". .EXAMPLE Enable-GitHubRepositoryVulnerabilityAlert -Owner 'octocat' -Repo 'hello-world' Enables vulnerability alerts for the 'octocat/hello-world' repository. .NOTES [Enable vulnerability alerts](https://docs.github.com/rest/repos/repos#enable-vulnerability-alerts) #> [CmdletBinding(SupportsShouldProcess)] [Alias('Enable-GitHubRepositoryVulnerabilityAlerts')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/vulnerability-alerts" Method = 'PUT' } if ($PSCmdlet.ShouldProcess("Vulnerability Alerts for [$Owner/$Repo]", "Enable")) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository] - Importing" #Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } filter Get-GitHubRepository { <# .SYNOPSIS Gets a specific repository or list of repositories. .DESCRIPTION Gets a specific repository or list of repositories based on parameter sets. If no parameters are specified, the authenticated user's repositories are returned. If a Username parameter is specified, the specified user's public repositories are returned. If the SinceId parameter is specified, the repositories with an ID greater than the specified ID are returned. If an Owner and Repo parameters are specified, the specified repository is returned. If the Owner and Repo parameters are specified, the specified repository is returned. .PARAMETER Type Specifies the types of repositories you want returned. .EXAMPLE Get-GitHubRepository Gets the repositories for the authenticated user. .EXAMPLE Get-GitHubRepository -Type 'owner' Gets the repositories owned by the authenticated user. .EXAMPLE Get-GitHubRepository -Username 'octocat' Gets the repositories for the specified user. .EXAMPLE Get-GitHubRepository -SinceID 123456789 Gets the repositories with an ID equals and greater than 123456789. .EXAMPLE Get-GitHubRepository -Owner 'github' -Repo 'octocat' Gets the specified repository. .NOTES [List repositories for the authenticated user](https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user) [Get a repository](https://docs.github.com/rest/repos/repos#get-a-repository) [List public repositories](https://docs.github.com/rest/repos/repos#list-public-repositories) [List organization repositories](https://docs.github.com/rest/repos/repos#list-organization-repositories) [List repositories for a user](https://docs.github.com/rest/repos/repos#list-repositories-for-a-user) #> [CmdletBinding(DefaultParameterSetName = 'MyRepos_Type')] param ( #Limit results to repositories with the specified visibility. [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [ValidateSet('all', 'public', 'private')] [string] $Visibility = 'all', # Comma-separated list of values. Can include: # - owner: Repositories that are owned by the authenticated user. # - collaborator: Repositories that the user has been added to as a collaborator. # - organization_member: Repositories that the user has access to through being a member of an organization. # This includes every repository on every team that the user is on. # Default: owner, collaborator, organization_member [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [ValidateSet('owner', 'collaborator', 'organization_member')] [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'), # A repository ID. Only return repositories with an ID greater than this ID. [Parameter(ParameterSetName = 'ListByID')] [int] $SinceID = 0, # Only show repositories updated after the given time. [Parameter(ParameterSetName = 'MyRepos_Type')] [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [datetime] $Since, # Only show repositories updated before the given time. [Parameter(ParameterSetName = 'MyRepos_Type')] [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [datetime] $Before, # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'ByName')] [Parameter(ParameterSetName = 'ListByOrg')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter( Mandatory, ParameterSetName = 'ByName' )] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'ListByUser' )] [Alias('login')] [string] $Username, # The property to sort the results by. [Parameter(ParameterSetName = 'MyRepos_Type')] [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')] [Parameter(ParameterSetName = 'ListByOrg')] [Parameter(ParameterSetName = 'ListByUser')] [ValidateSet('created', 'updated', 'pushed', 'full_name')] [string] $Sort = 'created', # The order to sort by. # Default: asc when using full_name, otherwise desc. [Parameter(ParameterSetName = 'MyRepos')] [Parameter(ParameterSetName = 'ListByOrg')] [Parameter(ParameterSetName = 'ListByUser')] [ValidateSet('asc', 'desc')] [string] $Direction, # The number of results per page (max 100). [Parameter(ParameterSetName = 'MyRepos')] [Parameter(ParameterSetName = 'ListByOrg')] [Parameter(ParameterSetName = 'ListByUser')] [ValidateRange(1, 100)] [int] $PerPage = 30 ) dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary if ($PSCmdlet.ParameterSetName -in 'MyRepos_Type', 'ListByOrg', 'ListByUser') { switch ($PSCmdlet.ParameterSetName) { 'MyRepos_Type' { $ValidateSet = 'all', 'owner', 'public', 'private', 'member' } 'ListByOrg' { $ValidateSet = 'all', 'public', 'private', 'forks', 'sources', 'member' } 'ListByUser' { $ValidateSet = 'all', 'owner', 'member' } } $dynParam = @{ Name = 'Type' ParameterSetName = $PSCmdlet.ParameterSetName Type = [string] Mandatory = $false ValidateSet = $ValidateSet DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam } return $DynamicParamDictionary } begin { $Type = $PSBoundParameters['Type'] } process { switch ($PSCmdlet.ParameterSetName) { 'MyRepos_Type' { $params = @{ Type = $Type Sort = $Sort Direction = $Direction PerPage = $PerPage Since = $Since Before = $Before } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues Get-GitHubMyRepositories @params } 'MyRepos_Aff-Vis' { $params = @{ Visibility = $Visibility Affiliation = $Affiliation Sort = $Sort Direction = $Direction PerPage = $PerPage Since = $Since Before = $Before } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues Get-GitHubMyRepositories @params } 'ByName' { $params = @{ Owner = $Owner Repo = $Repo } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues Get-GitHubRepositoryByName @params } 'ListByID' { $params = @{ Since = $SinceID } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues Get-GitHubRepositoryListByID @params } 'ListByOrg' { $params = @{ Owner = $Owner Type = $Type Sort = $Sort Direction = $Direction PerPage = $PerPage } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues Get-GitHubRepositoryListByOrg @params } 'ListByUser' { $params = @{ Username = $Username Type = $Type Sort = $Sort Direction = $Direction PerPage = $PerPage } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues Get-GitHubRepositoryListByUser @params } } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity] - Importing" filter Get-GitHubRepositoryActivity { <# .SYNOPSIS List repository activities .DESCRIPTION Lists a detailed history of changes to a repository, such as pushes, merges, force pushes, and branch changes, and associates these changes with commits and users. For more information about viewing repository activity, see "[Viewing activity and data for your repository](https://docs.github.com/repositories/viewing-activity-and-data-for-your-repository)." .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Direction 'asc' .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -PerPage 100 .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Before '2021-01-01T00:00:00Z' .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -After '2021-01-01T00:00:00Z' .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Ref 'refs/heads/main' .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Actor 'octocat' .EXAMPLE $params = @{ Owner = 'PSModule' Repo = 'GitHub' TimePeriod = 'day' } Get-GitHubRepositoryActivity @params | Select-Object -Property @{n='actor';e={$_.actor.login}},activity_type,ref,timestamp Gets the activity for the past 24 hours and selects the actor, activity type, ref, and timestamp. .EXAMPLE Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -ActivityType 'push','force_push' .NOTES [List repository activities](https://docs.github.com/rest/repos/repos#list-repository-activities) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The direction to sort the results by. [Parameter()] [ValidateSet('asc', 'desc')] [string] $Direction = 'desc', # The number of results per page (max 100). # Default: 30 [Parameter()] [ValidateRange(1, 100)] [Alias('per_page')] [int] $PerPage = 30, # A cursor, as given in the Link header. If specified, the query only searches for results before this cursor. [Parameter(ParameterSetName = 'BeforeAfter')] [string] $Before, # A cursor, as given in the Link header. If specified, the query only searches for results after this cursor. [Parameter(ParameterSetName = 'BeforeAfter')] [string] $After, # The Git reference for the activities you want to list. # The ref for a branch can be formatted either as refs/heads/BRANCH_NAME or BRANCH_NAME, where BRANCH_NAME is the name of your branch. [Parameter()] [string] $Ref, # The GitHub username to use to filter by the actor who performed the activity. [Parameter()] [string] $Actor, # The time period to filter by. # For example,day will filter for activity that occurred in the past 24 hours, # and week will filter for activity that occurred in the past 7 days (168 hours). [Parameter()] [ValidateSet('day', 'week', 'month', 'quarter', 'year')] [Alias('time_period')] [string] $TimePeriod, # The activity type to filter by. # For example,you can choose to filter by 'force_push', to see all force pushes to the repository. [Parameter()] [ValidateSet('push', 'force_push', 'branch_creation', 'branch_deletion', 'pr_merge', 'merge_queue_merge')] [Alias('activity_type')] [string] $ActivityType ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/activity" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError] - Importing" filter Get-GitHubRepositoryCodeownersError { <# .SYNOPSIS List CODEOWNERS errors .DESCRIPTION List any syntax errors that are detected in the CODEOWNERS file. For more information about the correct CODEOWNERS syntax, see "[About code owners](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners)." .EXAMPLE Get-GitHubRepositoryCodeownersError -Owner 'PSModule' -Repo 'GitHub' Gets the CODEOWNERS errors for the repository. .NOTES [List CODEOWNERS errors](https://docs.github.com/rest/repos/repos#list-codeowners-errors) #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # A branch, tag or commit name used to determine which version of the CODEOWNERS file to use. # Default: the repository's default branch (e.g. main) [Parameter()] [string] $Ref ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/codeowners/errors" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor] - Importing" filter Get-GitHubRepositoryContributor { <# .SYNOPSIS List repository contributors .DESCRIPTION Lists contributors to the specified repository and sorts them by the number of commits per contributor in descending order. This endpoint may return information that is a few hours old because the GitHub REST API caches contributor data to improve performance. GitHub identifies contributors by author email address. This endpoint groups contribution counts by GitHub user, which includes all associated email addresses. To improve performance, only the first 500 author email addresses in the repository link to GitHub users. The rest will appear as anonymous contributors without associated GitHub user information. .EXAMPLE Get-GitHubRepositoryContributor -Owner 'PSModule' -Repo 'GitHub' Gets all contributors to the GitHub repository. .NOTES [List repository contributors](https://docs.github.com/rest/repos/repos#list-repository-contributors) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # Wether to include anonymous contributors in results. [Parameter()] [switch] $Anon, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/contributors" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork] - Importing" filter Get-GitHubRepositoryFork { <# .SYNOPSIS List forks .DESCRIPTION List forks of a named repository. .EXAMPLE Get-GitHubRepositoryFork -Owner 'octocat' -Repo 'Hello-World' List forks of the 'Hello-World' repository owned by 'octocat'. .NOTES [List forks](https://docs.github.com/rest/repos/forks#list-forks) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The direction to sort the results by. [Parameter()] [ValidateSet('newest', 'oldest', 'stargazers', 'watchers')] [string] $Sort = 'newest', # The number of results per page. [Parameter()] [ValidateRange(1, 100)] [Alias('per_page')] [int] $PerPage = 30 ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/forks" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage] - Importing" filter Get-GitHubRepositoryLanguage { <# .SYNOPSIS List repository languages .DESCRIPTION Lists languages for the specified repository. The value shown for each language is the number of bytes of code written in that language. .EXAMPLE Get-GitHubRepositoryLanguage -Owner 'octocat' -Repo 'hello-world' Gets the languages for the 'hello-world' repository owned by 'octocat'. .NOTES [List repository languages](https://docs.github.com/rest/repos/repos#list-repository-languages) #> [CmdletBinding()] [Alias('Get-GitHubRepositoryLanguages')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/languages" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix] - Importing" filter Get-GitHubRepositorySecurityFix { <# .SYNOPSIS Check if automated security fixes are enabled for a repository .DESCRIPTION Shows whether automated security fixes are enabled, disabled or paused for a repository. The authenticated user must have admin read access to the repository. For more information, see "[Configuring automated security fixes](https://docs.github.com/articles/configuring-automated-security-fixes)". .EXAMPLE Get-GitHubRepositorySecurityFix -Owner 'PSModule' -Repo 'GitHub' Gets the automated security fixes status for the GitHub repository. .NOTES [Check if automated security fixes are enabled for a repository](https://docs.github.com/rest/repos/repos#check-if-automated-security-fixes-are-enabled-for-a-repository) #> [Alias('Get-GitHubRepoSecurityFixes')] [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/automated-security-fixes" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag] - Importing" filter Get-GitHubRepositoryTag { <# .SYNOPSIS List repository tags .DESCRIPTION List repository tags .EXAMPLE Get-GitHubRepositoryTag -Owner 'PSModule' -Repo 'GitHub' Gets all tags of the GitHub repository. .NOTES [List repository tags](https://docs.github.com/rest/repos/repos#list-repository-tags) #> [CmdletBinding()] [Alias('Get-GitHubRepositoryTags')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/tags" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam] - Importing" filter Get-GitHubRepositoryTeam { <# .SYNOPSIS List repository teams .DESCRIPTION Lists the teams that have access to the specified repository and that are also visible to the authenticated user. For a public repository, a team is listed only if that team added the public repository explicitly. Personal access tokens require the following scopes: * `public_repo` to call this endpoint on a public repository * `repo` to call this endpoint on a private repository (this scope also includes public repositories) This endpoint is not compatible with fine-grained personal access tokens. .EXAMPLE Get-GitHubRepositoryTeam -Owner 'PSModule' -Repo 'GitHub' Lists the teams that have access to the specified repository and that are also visible to the authenticated user. .NOTES [List repository teams](https://docs.github.com/rest/repos/repos#list-repository-teams) #> [CmdletBinding()] [Alias('Get-GitHubRepositoryTeams')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/teams" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic] - Importing" filter Get-GitHubRepositoryTopic { <# .SYNOPSIS Get all repository topics .DESCRIPTION Get all repository topics .EXAMPLE .NOTES [Get all repository topics](https://docs.github.com/rest/repos/repos#get-all-repository-topics) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/topics" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response.names } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository] - Importing" filter Move-GitHubRepository { <# .SYNOPSIS Transfer a repository .DESCRIPTION A transfer request will need to be accepted by the new owner when transferring a personal repository to another user. The response will contain the original `owner`, and the transfer will continue asynchronously. For more details on the requirements to transfer personal and organization-owned repositories, see [about repository transfers](https://docs.github.com/articles/about-repository-transfers/). You must use a personal access token (classic) or an OAuth token for this endpoint. An installation access token or a fine-grained personal access token cannot be used because they are only granted access to a single account. .EXAMPLE Move-GitHubRepository -Owner 'PSModule' -Repo 'GitHub' -NewOwner 'GitHub' -NewName 'PowerShell' Moves the GitHub repository to the PSModule organization and renames it to GitHub. .NOTES [Transfer a repository](https://docs.github.com/rest/repos/repos#transfer-a-repository) #> [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The username or organization name the repository will be transferred to. [Parameter(Mandatory)] [Alias('new_owner')] [string] $NewOwner, # The new name to be given to the repository. [Parameter()] [Alias('new_name')] [string] $NewName, # ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories. [Parameter()] [Alias('team_ids')] [int[]] $TeamIds ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/transfer" Method = 'POST' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository] #region - From [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository] - Importing" #Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' } filter New-GitHubRepository { <# .SYNOPSIS Create a repository for a user or an organization. .DESCRIPTION Creates a new repository for a user or in a specified organization. **OAuth scope requirements** When using [OAuth](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/), authorizations must include: * `public_repo` scope or `repo` scope to create a public repository. Note: For GitHub AE, use `repo` scope to create an internal repository. * `repo` scope to create a private repository .EXAMPLE $params = @{ Name = 'Hello-World' Description = 'This is your first repository' Homepage = 'https://github.com' HasIssues = $true HasProjects = $true HasWiki = $true HasDiscussions = $true HasDownloads = $true IsTemplate = $true AutoInit = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true SquashMergeCommitTitle = 'PR_TITLE' SquashMergeCommitMessage = 'PR_BODY' } New-GitHubRepository @params Creates a new public repository named "Hello-World" owned by the authenticated user. .EXAMPLE $params = @{ Owner = 'PSModule' Name = 'Hello-World' Description = 'This is your first repository' Homepage = 'https://github.com' HasIssues = $true HasProjects = $true HasWiki = $true HasDownloads = $true IsTemplate = $true AutoInit = $true AllowSquashMerge = $true AllowAutoMerge = $true DeleteBranchOnMerge = $true SquashMergeCommitTitle = 'PR_TITLE' SquashMergeCommitMessage = 'PR_BODY' } New-GitHubRepository @params Creates a new public repository named "Hello-World" owned by the organization "PSModule". .EXAMPLE $params = @{ TemplateOwner = 'GitHub' TemplateRepo = 'octocat' Owner = 'PSModule' Name = 'MyNewRepo' IncludeAllBranches = $true Description = 'My new repo' Private = $true } New-GitHubRepository @params Creates a new private repository named `MyNewRepo` from the `octocat` template repository owned by `GitHub`. .EXAMPLE $params = @{ ForkOwner = 'octocat' ForkRepo = 'Hello-World' Owner = 'PSModule' Name = 'MyNewRepo' DefaultBranchOnly = $true } New-GitHubRepository @params Creates a new repository named `MyNewRepo` as a fork of `Hello-World` owned by `octocat`. Only the default branch will be forked. .NOTES https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template .PARAMETER GitignoreTemplate Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell". .PARAMETER LicenseTemplate Choose an open source license template that best suits your needs, and then use the license keyword as the license_template string. For example, "mit" or "mpl-2.0". .NOTES [Create a repository for the authenticated user](https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user) [Create an organization repository](https://docs.github.com/rest/repos/repos#create-an-organization-repository) #> [OutputType([pscustomobject])] [CmdletBinding( SupportsShouldProcess, DefaultParameterSetName = 'user' )] param ( # The account owner of the repository. The name is not case sensitive. [Parameter(ParameterSetName = 'org')] [Parameter(ParameterSetName = 'fork')] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository. [Parameter(ParameterSetName = 'fork')] [Parameter(Mandatory, ParameterSetName = 'user')] [Parameter(Mandatory, ParameterSetName = 'org')] [Parameter(Mandatory, ParameterSetName = 'template')] [string] $Name, # The account owner of the template repository. The name is not case sensitive. [Parameter( Mandatory, ParameterSetName = 'template' )] [Alias('template_owner')] [string] $TemplateOwner, # The name of the template repository without the .git extension. The name is not case sensitive. [Parameter( Mandatory, ParameterSetName = 'template' )] [Alias('template_repo')] [string] $TemplateRepo, # The account owner of the repository. The name is not case sensitive. [Parameter( Mandatory, ParameterSetName = 'fork' )] [string] $ForkOwner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter( Mandatory, ParameterSetName = 'fork' )] [string] $ForkRepo, # When forking from an existing repository, fork with only the default branch. [Parameter(ParameterSetName = 'fork')] [Alias('default_branch_only')] [switch] $DefaultBranchOnly, # A short description of the new repository. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Parameter(ParameterSetName = 'template')] [string] $Description, # Set to true to include the directory structure and files from all branches in the template repository, # and not just the default branch. [Parameter(ParameterSetName = 'template')] [Alias('include_all_branches')] [switch] $IncludeAllBranches, # A URL with more information about the repository. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [ValidateNotNullOrEmpty()] [uri] $Homepage, # The visibility of the repository. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Parameter(ParameterSetName = 'template')] [ValidateSet('public', 'private')] [string] $Visibility = 'public', # Whether issues are enabled. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('has_issues')] [switch] $HasIssues, # Whether projects are enabled. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('has_projects')] [switch] $HasProjects, # Whether the wiki is enabled. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('has_wiki')] [switch] $HasWiki, # Whether discussions are enabled. [Parameter(ParameterSetName = 'user')] [Alias('has_discussions')] [switch] $HasDiscussions, # Whether downloads are enabled. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('has_downloads')] [switch] $HasDownloads, # Whether this repository acts as a template that can be used to generate new repositories. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('is_template')] [switch] $IsTemplate, # The ID of the team that will be granted access to this repository. This is only valid when creating a repository in an organization. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('team_id')] [int] $TeamId, # Pass true to create an initial commit with empty README. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('auto_init')] [switch] $AutoInit, # Whether to allow squash merges for pull requests. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('allow_squash_merge')] [switch] $AllowSquashMerge, # Whether to allow merge commits for pull requests. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('allow_merge_commit')] [switch] $AllowMergeCommit, # Whether to allow rebase merges for pull requests. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('allow_rebase_merge')] [switch] $AllowRebaseMerge, # Whether to allow Auto-merge to be used on pull requests. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('allow_auto_merge')] [switch] $AllowAutoMerge, # Whether to delete head branches when pull requests are merged [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [Alias('delete_branch_on_merge')] [switch] $DeleteBranchOnMerge, # The default value for a squash merge commit title: # - PR_TITLE - default to the pull request's title. # - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit). [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')] [Alias('squash_merge_commit_title')] [string] $SquashMergeCommitTitle, # The default value for a squash merge commit message: # - PR_BODY - default to the pull request's body. # - COMMIT_MESSAGES - default to the branch's commit messages. # - BLANK - default to a blank commit message. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')] [Alias('squash_merge_commit_message')] [string] $SquashMergeCommitMessage, # The default value for a merge commit title. # - PR_TITLE - default to the pull request's title. # - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name). [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [ValidateSet('PR_TITLE', 'MERGE_MESSAGE')] [Alias('merge_commit_title')] [string] $MergeCommitTitle, # The default value for a merge commit message. # - PR_BODY - default to the pull request's body. # - PR_TITLE - default to the pull request's title. # - BLANK - default to a blank commit message. [Parameter(ParameterSetName = 'user')] [Parameter(ParameterSetName = 'org')] [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')] [Alias('merge_commit_message')] [string] $MergeCommitMessage ) dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ Name = 'GitignoreTemplate' Alias = 'gitignore_template' Type = [string] ValidateSet = Get-GitHubGitignoreList DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam $dynParam2 = @{ Name = 'LicenseTemplate' Alias = 'license_template' Type = [string] ValidateSet = Get-GitHubLicenseList | Select-Object -ExpandProperty key DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam2 return $DynamicParamDictionary } begin { $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate'] $LicenseTemplate = $PSBoundParameters['LicenseTemplate'] } process { if ($PSCmdlet.ParameterSetName -in 'user', 'org') { $params = @{ Owner = $Owner Name = $Name Description = $Description Homepage = $Homepage Visibility = $Visibility HasIssues = $HasIssues HasProjects = $HasProjects HasWiki = $HasWiki HasDiscussions = $HasDiscussions HasDownloads = $HasDownloads IsTemplate = $IsTemplate TeamId = $TeamId AutoInit = $AutoInit AllowSquashMerge = $AllowSquashMerge AllowMergeCommit = $AllowMergeCommit AllowRebaseMerge = $AllowRebaseMerge AllowAutoMerge = $AllowAutoMerge DeleteBranchOnMerge = $DeleteBranchOnMerge SquashMergeCommitTitle = $SquashMergeCommitTitle SquashMergeCommitMessage = $SquashMergeCommitMessage MergeCommitTitle = $MergeCommitTitle MergeCommitMessage = $MergeCommitMessage GitignoreTemplate = $GitignoreTemplate LicenseTemplate = $LicenseTemplate } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues } switch ($PSCmdlet.ParameterSetName) { 'user' { if ($PSCmdlet.ShouldProcess("repository for user [$Name]", 'Create')) { New-GitHubRepositoryUser @params } } 'org' { if ($PSCmdlet.ShouldProcess("repository for organization [$Owner/$Name]", 'Create')) { New-GitHubRepositoryOrg @params } } 'template' { if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] from template [$TemplateOwner/$TemplateRepo]", 'Create')) { $params = @{ TemplateOwner = $TemplateOwner TemplateRepo = $TemplateRepo Owner = $Owner Name = $Name IncludeAllBranches = $IncludeAllBranches Description = $Description Private = $Visibility -eq 'private' } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues New-GitHubRepositoryFromTemplate @params } } 'fork' { if ([string]::IsNullorEmpty($Name)) { $Name = $ForkRepo } if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepo]", 'Create')) { $params = @{ Owner = $ForkOwner Repo = $ForkRepo Organization = $Owner Name = $Name DefaultBranchOnly = $DefaultBranchOnly } Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues New-GitHubRepositoryAsFork @params } } } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository] - Importing" filter Remove-GitHubRepository { <# .SYNOPSIS Delete a repository .DESCRIPTION Deleting a repository requires admin access. If OAuth is used, the `delete_repo` scope is required. If an organization owner has configured the organization to prevent members from deleting organization-owned repositories, you will get a `403 Forbidden` response. .EXAMPLE Remove-GitHubRepository -Owner 'PSModule' -Repo 'Hello-World' Deletes the repository `Hello-World` in the `PSModule` organization. .NOTES [Delete a repository](https://docs.github.com/rest/repos/repos#delete-a-repository) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter(Mandatory)] [Alias('org')] [Alias('login')] [string] $Owner, # The name of the repository without the .git extension. The name is not case sensitive. [Parameter(Mandatory)] [string] $Repo ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("repo [$Owner/$Repo]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic] - Importing" filter Set-GitHubRepositoryTopic { <# .SYNOPSIS Replace all repository topics .DESCRIPTION Replace all repository topics .EXAMPLE Set-GitHubRepositoryTopic -Owner 'octocat' -Repo 'hello-world' -Names 'octocat', 'octo', 'octocat/hello-world' Replaces all topics for the repository 'octocat/hello-world' with the topics 'octocat', 'octo', 'octocat/hello-world'. .NOTES [Replace all repository topics](https://docs.github.com/rest/repos/repos#replace-all-repository-topics) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The number of results per page (max 100). [Parameter()] [Alias('Topics')] [string[]] $Names = @() ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $body.names = $body.names | ForEach-Object { $_.ToLower() } $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/topics" Method = 'PUT' Body = $body } if ($PSCmdlet.ShouldProcess("topics for repo [$Owner/$Repo]", 'Set')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response.names } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent] - Importing" filter Start-GitHubRepositoryEvent { <# .SYNOPSIS Create a repository dispatch event .DESCRIPTION You can use this endpoint to trigger a webhook event called `repository_dispatch` when you want activity that happens outside of GitHub to trigger a GitHub Actions workflow or GitHub App webhook. You must configure your GitHub Actions workflow or GitHub App to run when the `repository_dispatch` event occurs. For an example `repository_dispatch` webhook payload, see "[RepositoryDispatchEvent](https://docs.github.com/webhooks/event-payloads/#repository_dispatch)." The `client_payload` parameter is available for any extra information that your workflow might need. This parameter is a JSON payload that will be passed on when the webhook event is dispatched. For example, the `client_payload` can include a message that a user would like to send using a GitHub Actions workflow. Or the `client_payload` can be used as a test to debug your workflow. This endpoint requires write access to the repository by providing either: - Personal access tokens with `repo` scope. For more information, see "[Creating a personal access token for the command line](https://docs.github.com/articles/creating-a-personal-access-token-for-the-command-line)" in the GitHub Help documentation. - GitHub Apps with both `metadata:read` and `contents:read&write` permissions. This input example shows how you can use the `client_payload` as a test to debug your workflow. .EXAMPLE $params = @{ EventType = 'on-demand-test' ClientPayload = @{ unit = false integration = true } } Start-GitHubRepositoryEvent @params Starts a repository event with the name `on-demand-test` and a `client_payload` that includes `unit` and `integration`. .NOTES [Create a repository dispatch event](https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event) #> [CmdletBinding(SupportsShouldProcess)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # A custom webhook event name. Must be 100 characters or fewer. [Parameter(Mandatory)] [Alias('event_type')] [string] $EventType, # JSON payload with extra information about the webhook event that your action or workflow may use. # The maximum number of top-level properties is 10. [Parameter()] [Alias('client_payload')] [object] $ClientPayload ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/dispatches" Method = 'POST' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert] - Importing" filter Test-GitHubRepositoryVulnerabilityAlert { <# .SYNOPSIS Check if vulnerability alerts are enabled for a repository .DESCRIPTION Shows whether dependency alerts are enabled or disabled for a repository. The authenticated user must have admin read access to the repository. For more information, see "[About security alerts for vulnerable dependencies](https://docs.github.com/articles/about-security-alerts-for-vulnerable-dependencies)". .EXAMPLE Test-GitHubRepositoryVulnerabilityAlert -Owner 'PSModule' -Repo 'GitHub' Checks if vulnerability alerts are enabled for the PSModule/GitHub repository. .NOTES [Check if vulnerability alerts are enabled for a repository](https://docs.github.com/rest/repos/repos#list-repository-tags) #> [OutputType([bool])] [CmdletBinding()] [Alias('Test-GitHubRepositoryVulnerabilityAlerts')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/vulnerability-alerts" Method = 'GET' } try { (Invoke-GitHubAPI @inputObject).StatusCode -eq 204 } catch { if ($_.Exception.Response.StatusCode.Value__ -eq 404) { return $false } else { throw $_ } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert] #region - From [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository] - Importing" filter Update-GitHubRepository { <# .SYNOPSIS Update a repository .DESCRIPTION **Note**: To edit a repository's topics, use the [Replace all repository topics](https://docs.github.com/rest/repos/repos#replace-all-repository-topics) endpoint. .EXAMPLE Update-GitHubRepository -Name 'octocat' -Description 'Hello-World' -Homepage 'https://github.com' .EXAMPLE $params = @{ Owner = 'octocat' Repo = 'Hello-World' name = 'Hello-World-Repo description = 'This is your first repository' homepage = 'https://github.com' } Update-GitHubRepository @params .NOTES [Update a repository](https://docs.github.com/rest/repos/repos#update-a-repository) #> [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The name of the repository. [Parameter()] [string] $Name, # A short description of the repository. [Parameter()] [string] $Description, # A URL with more information about the repository. [Parameter()] [uri] $Homepage, # The visibility of the repository. [Parameter()] [ValidateSet('public', 'private')] [string] $Visibility, # Use the status property to enable or disable GitHub Advanced Security for this repository. # For more information, see "About GitHub Advanced Security." [Parameter()] [switch] $EnableAdvancedSecurity, # Use the status property to enable or disable secret scanning for this repository. # For more information, see "About secret scanning." [Parameter()] [switch] $EnableSecretScanning, # Use the status property to enable or disable secret scanning push protection for this repository. # For more information, see "Protecting pushes with secret scanning." [Parameter()] [switch] $EnableSecretScanningPushProtection, # Whether issues are enabled. [Parameter()] [Alias('has_issues')] [switch] $HasIssues, # Whether projects are enabled. [Parameter()] [Alias('has_projects')] [switch] $HasProjects, # Whether the wiki is enabled. [Parameter()] [Alias('has_wiki')] [switch] $HasWiki, # Whether this repository acts as a template that can be used to generate new repositories. [Parameter()] [Alias('is_template')] [switch] $IsTemplate, # Updates the default branch for this repository. [Parameter()] [Alias('default_branch')] [string] $DefaultBranch, # Whether to allow squash merges for pull requests. [Parameter()] [Alias('allow_squash_merge')] [switch] $AllowSquashMerge, # Whether to allow merge commits for pull requests. [Parameter()] [Alias('allow_merge_commit')] [switch] $AllowMergeCommit, # Whether to allow rebase merges for pull requests. [Parameter()] [Alias('allow_rebase_merge')] [switch] $AllowRebaseMerge, # Whether to allow Auto-merge to be used on pull requests. [Parameter()] [Alias('allow_auto_merge')] [switch] $AllowAutoMerge, # Whether to delete head branches when pull requests are merged [Parameter()] [Alias('delete_branch_on_merge')] [switch] $DeleteBranchOnMerge, # Either true to always allow a pull request head branch that is behind its base branch # to be updated even if it is not required to be up to date before merging, or false otherwise. [Parameter()] [Alias('allow_update_branch')] [switch] $AllowUpdateMerge, # The default value for a squash merge commit title: # - PR_TITLE - default to the pull request's title. # - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit). [Parameter()] [ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')] [Alias('squash_merge_commit_title')] [string] $SquashMergeCommitTitle, # The default value for a squash merge commit message: # - PR_BODY - default to the pull request's body. # - COMMIT_MESSAGES - default to the branch's commit messages. # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')] [Alias('squash_merge_commit_message')] [string] $SquashMergeCommitMessage, # The default value for a merge commit title. # - PR_TITLE - default to the pull request's title. # - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name). [Parameter()] [ValidateSet('PR_TITLE', 'MERGE_MESSAGE')] [Alias('merge_commit_title')] [string] $MergeCommitTitle, # The default value for a merge commit message. # - PR_BODY - default to the pull request's body. # - PR_TITLE - default to the pull request's title. # - BLANK - default to a blank commit message. [Parameter()] [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')] [Alias('merge_commit_message')] [string] $MergeCommitMessage, # Whether to archive this repository. false will unarchive a previously archived repository. [Parameter()] [switch] $Archived, # Either true to allow private forks, or false to prevent private forks. [Parameter()] [Alias('allow_forking')] [switch] $AllowForking, # Either true to require contributors to sign off on web-based commits, # or false to not require contributors to sign off on web-based commits. [Parameter()] [Alias('web_commit_signoff_required')] [switch] $WebCommitSignoffRequired ) $body = @{ name = $Name description = $Description homepage = $Homepage visibility = $Visibility private = $Visibility -eq 'private' default_branch = $DefaultBranch squash_merge_commit_title = $SquashMergeCommitTitle squash_merge_commit_message = $SquashMergeCommitMessage merge_commit_title = $MergeCommitTitle merge_commit_message = $MergeCommitMessage advanced_security = if ($EnableAdvancedSecurity.IsPresent) { @{ status = if ($EnableAdvancedSecurity) { 'enabled' } else { 'disabled' } } } else { $null } secret_scanning = if ($EnableSecretScanning.IsPresent) { @{ status = if ($EnableSecretScanning) { 'enabled' } else { 'disabled' } } } else { $null } secret_scanning_push_protection = if ($EnableSecretScanningPushProtection.IsPresent) { @{ status = if ($EnableSecretScanningPushProtection) { 'enabled' } else { 'disabled' } } } else { $null } has_issues = if ($HasIssues.IsPresent) { $HasIssues } else { $null } has_projects = if ($HasProjects.IsPresent) { $HasProjects } else { $null } has_wiki = if ($HasWiki.IsPresent) { $HasWiki } else { $null } is_template = if ($IsTemplate.IsPresent) { $IsTemplate } else { $null } allow_squash_merge = if ($AllowSquashMerge.IsPresent) { $AllowSquashMerge } else { $null } allow_merge_commit = if ($AllowMergeCommit.IsPresent) { $AllowMergeCommit } else { $null } allow_rebase_merge = if ($AllowRebaseMerge.IsPresent) { $AllowRebaseMerge } else { $null } allow_auto_merge = if ($AllowAutoMerge.IsPresent) { $AllowAutoMerge } else { $null } allow_update_branch = if ($AllowUpdateMerge.IsPresent) { $AllowUpdateMerge } else { $null } delete_branch_on_merge = if ($DeleteBranchOnMerge.IsPresent) { $DeleteBranchOnMerge } else { $null } archived = if ($Archived.IsPresent) { $Archived } else { $null } allow_forking = if ($AllowForking.IsPresent) { $AllowForking } else { $null } web_commit_signoff_required = if ($WebCommitSignoffRequired.IsPresent) { $WebCommitSignoffRequired } else { $null } } Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo" Method = 'PATCH' Body = $body } if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Repo]", 'Update')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - Done" #endregion - From [functions] - [public] - [Repositories] - [Repositories] #region - From [functions] - [public] - [Repositories] - [RuleSuite] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - Processing folder" #region - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite] - Importing" filter Get-GitHubRepositoryRuleSuite { <# .SYNOPSIS List repository rule suites or a rule suite by ID. .DESCRIPTION Lists suites of rule evaluations at the repository level. If an ID is specified, gets information about a suite of rule evaluations from within a repository. For more information, see"[Managing rulesets for a repository](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository#viewing-insights-for-rulesets)." .EXAMPLE $params = @{ Owner = 'octocat' Repo = 'hello-world' Ref = 'main' TimePeriod = 'day' ActorName = 'octocat' RuleSuiteResult = 'all' } Get-GitHubRepositoryRuleSuite @params Gets a list of rule suites for the main branch of the hello-world repository owned by octocat. .EXAMPLE Get-GitHubRepositoryRuleSuite -Owner 'octocat' -Repo 'hello-world' -RuleSuiteId 123456789 Gets information about a suite of rule evaluations with ID 123456789 from within the octocat/hello-world repository. .NOTES [List repository rule suites](https://docs.github.com/rest/repos/rule-suites#list-repository-rule-suites) [Get a repository rule suite](https://docs.github.com/rest/repos/rule-suites#get-a-repository-rule-suite) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The name of the ref. Cannot contain wildcard characters. # When specified, only rule evaluations triggered for this ref will be returned. [Parameter()] [string] $Ref, # The time period to filter by. # For example,day will filter for rule suites that occurred in the past 24 hours, # and week will filter for insights that occurred in the past 7 days (168 hours). [Parameter()] [ValidateSet('hour', 'day', 'week', 'month')] [string] $TimePeriod = 'day', # The handle for the GitHub user account to filter on. When specified, only rule evaluations triggered by this actor will be returned. [Parameter()] [string] $ActorName, # The rule results to filter on. When specified, only suites with this result will be returned. [Parameter()] [ValidateSet('pass', 'fail', 'bypass', 'all')] [string] $RuleSuiteResult = 'all', # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30, # The unique identifier of the rule suite result. To get this ID, you can use GET /repos/ { owner }/ { repo }/rulesets/rule-suites for repositories and GET /orgs/ { org }/rulesets/rule-suites for organizations. [Parameter( Mandatory, ParameterSetName = 'ById' )] [int] $RuleSuiteId ) switch ($PSCmdlet.ParameterSetName) { 'Default' { $params = @{ Owner = $Owner Repo = $Repo Ref = $Ref TimePeriod = $TimePeriod ActorName = $ActorName RuleSuiteResult = $RuleSuiteResult PerPage = $PerPage } Get-GitHubRepositoryRuleSuiteList @params } 'ById' { $params = @{ Owner = $Owner Repo = $Repo RuleSuiteId = $RuleSuiteId } Get-GitHubRepositoryRuleSuiteById @params } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite] - Done" #endregion - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite] #region - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById] - Importing" filter Get-GitHubRepositoryRuleSuiteById { <# .SYNOPSIS Get a repository rule suite .DESCRIPTION Gets information about a suite of rule evaluations from within a repository. For more information, see "[Managing rulesets for a repository](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository#viewing-insights-for-rulesets)." .EXAMPLE Get-GitHubRepositoryRuleSuiteById -Owner 'octocat' -Repo 'hello-world' -RuleSuiteId 123456789 Gets information about a suite of rule evaluations with ID 123456789 from within the octocat/hello-world repository. .NOTES [Get a repository rule suite](https://docs.github.com/rest/repos/rule-suites#get-a-repository-rule-suite) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')] [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the rule suite result. To get this ID, you can use GET /repos/ { owner }/ { repo }/rulesets/rule-suites for repositories and GET /orgs/ { org }/rulesets/rule-suites for organizations. [Parameter(Mandatory)] [int] $RuleSuiteId ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/rulesets/rule-suites/$RuleSuiteId" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById] - Done" #endregion - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById] #region - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList] - Importing" filter Get-GitHubRepositoryRuleSuiteList { <# .SYNOPSIS List repository rule suites .DESCRIPTION Lists suites of rule evaluations at the repository level. For more information, see"[Managing rulesets for a repository](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository#viewing-insights-for-rulesets)." .EXAMPLE $params = @{ Owner = 'octocat' Repo = 'hello-world' Ref = 'main' TimePeriod = 'day' ActorName = 'octocat' RuleSuiteResult = 'all' } Get-GitHubRepositoryRuleSuiteList @params Gets a list of rule suites for the main branch of the hello-world repository owned by octocat. .NOTES [List repository rule suites](https://docs.github.com/rest/repos/rule-suites#list-repository-rule-suites) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')] [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The name of the ref. Cannot contain wildcard characters. # When specified, only rule evaluations triggered for this ref will be returned. [Parameter()] [string] $Ref, # The time period to filter by. # For example,day will filter for rule suites that occurred in the past 24 hours, # and week will filter for insights that occurred in the past 7 days (168 hours). [Parameter()] [ValidateSet('hour', 'day', 'week', 'month')] [string] $TimePeriod = 'day', # The handle for the GitHub user account to filter on. When specified, only rule evaluations triggered by this actor will be returned. [Parameter()] [string] $ActorName, # The rule results to filter on. When specified, only suites with this result will be returned. [Parameter()] [ValidateSet('pass', 'fail', 'bypass', 'all')] [string] $RuleSuiteResult = 'all', # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object { $paramName = $_.Key $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue $providedValue = $PSBoundParameters[$paramName] Write-Verbose "[$paramName]" Write-Verbose " - Default: [$paramDefaultValue]" Write-Verbose " - Provided: [$providedValue]" if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) { Write-Verbose ' - Using default value' $PSBoundParameters[$paramName] = $paramDefaultValue } else { Write-Verbose ' - Using provided value' } } $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo' -RemoveTypes 'SwitchParameter' $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/rulesets/rule-suites" Method = 'GET' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList] - Done" #endregion - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - Done" #endregion - From [functions] - [public] - [Repositories] - [RuleSuite] #region - From [functions] - [public] - [Repositories] - [Tags] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - Processing folder" #region - From [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection] - Importing" filter Get-GitHubRepositoryTagProtection { <# .SYNOPSIS List tag protection states for a repository .DESCRIPTION This returns the tag protection states of a repository. This information is only available to repository administrators. .EXAMPLE Get-GitHubRepositoryTagProtection -Owner 'octocat' -Repo 'hello-world' Gets the tag protection states of the 'hello-world' repository. .NOTES [List tag protection states for a repository](https://docs.github.com/rest/repos/tags#list-tag-protection-states-for-a-repository) #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/tags/protection" Method = 'GET' } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection] - Done" #endregion - From [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection] #region - From [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection] - Importing" filter New-GitHubRepositoryTagProtection { <# .SYNOPSIS Create a tag protection state for a repository .DESCRIPTION This creates a tag protection state for a repository. This endpoint is only available to repository administrators. .EXAMPLE New-GitHubRepositoryTagProtection -Owner 'octocat' -Repo 'hello-world' -Pattern 'v1.*' Creates a tag protection state for the 'hello-world' repository with the pattern 'v1.*'. .NOTES [Create a tag protection state for a repository](https://docs.github.com/rest/repos/tags#create-a-tag-protection-state-for-a-repository) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # An optional glob pattern to match against when enforcing tag protection. [Parameter(Mandatory)] [string] $Pattern ) $body['pattern'] = $Pattern $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/tags/protection" Method = 'POST' Body = $body } if ($PSCmdlet.ShouldProcess("tag protection state on pattern [$Pattern] for repository [$Owner/$Repo]", 'Create')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection] - Done" #endregion - From [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection] #region - From [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection] - Importing" filter Remove-GitHubRepositoryTagProtection { <# .SYNOPSIS Delete a tag protection state for a repository .DESCRIPTION This deletes a tag protection state for a repository. This endpoint is only available to repository administrators. .EXAMPLE Remove-GitHubRepositoryTagProtection -Owner 'octocat' -Repo 'hello-world' -TagProtectionId 1 Deletes the tag protection state with the ID 1 for the 'hello-world' repository. .NOTES [Delete a tag protection state for a repository](https://docs.github.com/rest/repos/tags#delete-a-tag-protection-state-for-a-repository) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The account owner of the repository. The name is not case sensitive. [Parameter()] [Alias('org')] [string] $Owner = (Get-GitHubContextSetting -Name Owner), # The name of the repository without the .git extension. The name is not case sensitive. [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo), # The unique identifier of the tag protection. [Parameter(Mandatory)] [int] $TagProtectionId ) $inputObject = @{ APIEndpoint = "/repos/$Owner/$Repo/tags/protection/$TagProtectionId" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("tag protection state with ID [$TagProtectionId] for repository [$Owner/$Repo]", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection] - Done" #endregion - From [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - Done" #endregion - From [functions] - [public] - [Repositories] - [Tags] Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - Done" #endregion - From [functions] - [public] - [Repositories] #region - From [functions] - [public] - [Status] Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - Processing folder" #region - From [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance] Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance] - 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 [Scheduled maintenances](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] - [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance] - Done" #endregion - From [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance] #region - From [functions] - [public] - [Status] - [Get-GitHubStatus] Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatus] - 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 [Summary](https://www.githubstatus.com/api#summary) [Status](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] - [functions] - [public] - [Status] - [Get-GitHubStatus] - Done" #endregion - From [functions] - [public] - [Status] - [Get-GitHubStatus] #region - From [functions] - [public] - [Status] - [Get-GitHubStatusComponent] Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatusComponent] - Importing" function Get-GitHubStatusComponent { <# .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-GitHubStatusComponent Gets the status of GitHub components .NOTES [Components](https://www.githubstatus.com/api#components) #> [OutputType([pscustomobject[]])] [Alias('Get-GitHubStatusComponents')] [CmdletBinding()] param() $APIURI = 'https://www.githubstatus.com/api/v2/components.json' $response = Invoke-RestMethod -Uri $APIURI -Method Get $response.components } Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatusComponent] - Done" #endregion - From [functions] - [public] - [Status] - [Get-GitHubStatusComponent] #region - From [functions] - [public] - [Status] - [Get-GitHubStatusIncident] Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatusIncident] - Importing" function Get-GitHubStatusIncident { <# .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-GitHubStatusIncident Gets the status of GitHub incidents .EXAMPLE Get-GitHubStatusIncident -Unresolved Gets the status of GitHub incidents that are unresolved .NOTES [Incidents](https://www.githubstatus.com/api#incidents) #> [OutputType([pscustomobject[]])] [Alias('Get-GitHubStatusIncidents')] [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] - [functions] - [public] - [Status] - [Get-GitHubStatusIncident] - Done" #endregion - From [functions] - [public] - [Status] - [Get-GitHubStatusIncident] Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - Done" #endregion - From [functions] - [public] - [Status] #region - From [functions] - [public] - [Teams] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - Processing folder" #region - From [functions] - [public] - [Teams] - [Get-GitHubRepoTeam] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubRepoTeam] - Importing" filter Get-GitHubRepoTeam { <# .NOTES [List repository teams](https://docs.github.com/rest/reference/repos#get-a-repository) #> [CmdletBinding()] param ( [Parameter()] [string] $Owner = (Get-GitHubContextSetting -Name Owner), [Parameter()] [string] $Repo = (Get-GitHubContextSetting -Name Repo) ) $inputObject = @{ Method = 'Get' APIEndpoint = "/repos/$Owner/$Repo/teams" } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubRepoTeam] - Done" #endregion - From [functions] - [public] - [Teams] - [Get-GitHubRepoTeam] #region - From [functions] - [public] - [Teams] - [Get-GitHubTeamByName] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamByName] - Importing" function Get-GitHubTeamByName { <# .SYNOPSIS Get a team by name .DESCRIPTION Gets a team using the team's slug. To create the slug, GitHub replaces special characters in the name string, changes all words to lowercase, and replaces spaces with a - separator. For example, "My TEam Näme" would become my-team-name. .EXAMPLE Get-GitHubTeamByName -Organization 'github' -Name 'my-team-name' .NOTES [Get team by name](https://docs.github.com/en/rest/teams/teams#get-a-team-by-name) #> [OutputType([void])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # The slug of the team name. [Parameter(Mandatory)] [Alias('Team', 'TeamName', 'slug', 'team_slug')] [string] $Name, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name DefaultContext) ) $inputObject = @{ Context = $Context Method = 'Get' APIEndpoint = "/orgs/$Organization/teams/$Name" } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamByName] - Done" #endregion - From [functions] - [public] - [Teams] - [Get-GitHubTeamByName] #region - From [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg] - Importing" function Get-GitHubTeamListByOrg { <# .SYNOPSIS List teams .DESCRIPTION Lists all teams in an organization that are visible to the authenticated user. .EXAMPLE Get-GitHubTeamListByOrg -Organization 'github' .NOTES [List teams](https://docs.github.com/rest/teams/teams#list-teams) #> [OutputType([pscustomobject])] [CmdletBinding()] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name DefaultContext) ) $inputObject = @{ Context = $Context Method = 'Get' APIEndpoint = "/orgs/$Organization/teams" } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg] - Done" #endregion - From [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg] #region - From [functions] - [public] - [Teams] - [New-GitHubTeam] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [New-GitHubTeam] - Importing" function New-GitHubTeam { <# .SYNOPSIS Create a team .DESCRIPTION To create a team, the authenticated user must be a member or owner of `{org}`. By default, organization members can create teams. Organization owners can limit team creation to organization owners. For more information, see "[Setting team creation permissions](https://docs.github.com/articles/setting-team-creation-permissions-in-your-organization)." When you create a new team, you automatically become a team maintainer without explicitly adding yourself to the optional array of `maintainers`. For more information, see "[About teams](https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/about-teams)". .EXAMPLE $params = @{ Organization = 'github' Name = 'team-name' Description = 'A new team' Maintainers = 'octocat' RepoNames = 'github/octocat' Privacy = 'closed' Permission = 'pull' } New-GitHubTeam @params .NOTES [Create a team](https://docs.github.com/rest/teams/teams#create-a-team) #> [CmdletBinding(SupportsShouldProcess)] param( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # The name of the team. [Parameter(Mandatory)] [string] $Name, # The description of the team. [Parameter()] [string] $Description, # List GitHub IDs for organization members who will become team maintainers. [Parameter()] [string[]] $Maintainers, # The full name (e.g., "organization-name/repository-name") of repositories to add the team to. [Parameter()] [string[]] $RepoNames, # The level of privacy this team should have. The options are: # For a non-nested team: # - secret - only visible to organization owners and members of this team. # - closed - visible to all members of this organization. # Default: secret # For a parent or child team: # - closed - visible to all members of this organization. # Default for child team: closed [Parameter()] [ValidateSet('secret', 'closed')] [string] $Privacy = 'closed', # The notification setting the team has chosen. The options are: # notifications_enabled - team members receive notifications when the team is @mentioned. # notifications_disabled - no one receives notifications. # Default: notifications_enabled [Parameter()] [ValidateSet('notifications_enabled', 'notifications_disabled')] [string] $NotificationSetting, # Closing down notice. The permission that new repositories will be added to the team with when none is specified. [Parameter()] [ValidateSet('pull', 'push')] [string] $Permission = 'pull', # The ID of a team to set as the parent team. [Parameter()] [int] $ParentTeamID, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name DefaultContext) ) $body = @{ name = $Name description = $Description maintainers = $Maintainers repo_names = $RepoNames privacy = $Privacy notification_setting = $NotificationSetting permission = $Permission parent_team_id = $ParentTeamID } $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ Context = $Context Method = 'POST' Body = $body APIEndpoint = "/orgs/$Organization/teams" } if ($PSCmdlet.ShouldProcess("'$Name' in '$Organization'", 'Create team')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [New-GitHubTeam] - Done" #endregion - From [functions] - [public] - [Teams] - [New-GitHubTeam] #region - From [functions] - [public] - [Teams] - [Remove-GitHubTeam] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Remove-GitHubTeam] - Importing" function Remove-GitHubTeam { <# .SYNOPSIS Delete a team .DESCRIPTION To delete a team, the authenticated user must be an organization owner or team maintainer. If you are an organization owner, deleting a parent team will delete all of its child teams as well. .EXAMPLE Remove-GitHubTeam -Organization 'github' -Name 'team-name' .NOTES [Delete a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#delete-a-team) #> [OutputType([void])] [CmdletBinding(SupportsShouldProcess)] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # The slug of the team name. [Parameter(Mandatory)] [Alias('Team', 'TeamName', 'slug', 'team_slug')] [string] $Name, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name DefaultContext) ) $inputObject = @{ Context = $Context Method = 'Delete' APIEndpoint = "/orgs/$Organization/teams/$Name" } if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Delete')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Remove-GitHubTeam] - Done" #endregion - From [functions] - [public] - [Teams] - [Remove-GitHubTeam] #region - From [functions] - [public] - [Teams] - [Update-GitHubTeam] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Update-GitHubTeam] - Importing" function Update-GitHubTeam { <# .SYNOPSIS Update a team .DESCRIPTION To edit a team, the authenticated user must either be an organization owner or a team maintainer. .EXAMPLE $params = @{ Organization = 'github' Name = 'team-name' NewName = 'new-team-name' Description = 'A new team' Privacy = 'closed' NotificationSetting = 'notifications_enabled' Permission = 'pull' ParentTeamID = 123456 } Update-GitHubTeam @params .NOTES [Update a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#update-a-team) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The organization name. The name is not case sensitive. [Parameter(Mandatory)] [Alias('Org')] [string] $Organization, # The slug of the team name. [Parameter(Mandatory)] [Alias('Team', 'TeamName', 'slug', 'team_slug')] [string] $Name, # The new team name. [Parameter()] [Alias()] [string] $NewName, # The description of the team. [Parameter()] [string] $Description, # The level of privacy this team should have. The options are: # For a non-nested team: # - secret - only visible to organization owners and members of this team. # - closed - visible to all members of this organization. # Default: secret # For a parent or child team: # - closed - visible to all members of this organization. # Default for child team: closed [Parameter()] [ValidateSet('secret', 'closed')] [string] $Privacy = 'closed', # The notification setting the team has chosen. The options are: # notifications_enabled - team members receive notifications when the team is @mentioned. # notifications_disabled - no one receives notifications. # Default: notifications_enabled [Parameter()] [ValidateSet('notifications_enabled', 'notifications_disabled')] [string] $NotificationSetting, # Closing down notice. The permission that new repositories will be added to the team with when none is specified. [Parameter()] [ValidateSet('pull', 'push')] [string] $Permission = 'pull', # The ID of a team to set as the parent team. [Parameter()] [int] $ParentTeamID, # The context to run the command in [Parameter()] [string] $Context = (Get-GitHubConfig -Name DefaultContext) ) $body = @{ name = $NewName description = $Description privacy = $Privacy notification_setting = $NotificationSetting permission = $Permission parent_team_id = $ParentTeamID } $body | Remove-HashtableEntry -NullOrEmptyValues $inputObject = @{ Context = $Context Method = 'Patch' APIEndpoint = "/orgs/$Organization/teams/$Name" Body = $body } if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Update')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Update-GitHubTeam] - Done" #endregion - From [functions] - [public] - [Teams] - [Update-GitHubTeam] Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - Done" #endregion - From [functions] - [public] - [Teams] #region - From [functions] - [public] - [Users] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - Processing folder" #region - From [functions] - [public] - [Users] - [Blocking] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - Processing folder" #region - From [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser] - 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 [Block a user](https://docs.github.com/rest/users/blocking#block-a-user) [Block a user from an organization](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')] [string] $OrganizationName ) if ($OrganizationName) { Block-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username } else { Block-GitHubUserByUser -Username $Username } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser] - Done" #endregion - From [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser] #region - From [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser] - 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 [List users blocked by the authenticated user](https://docs.github.com/rest/users/blocking#list-users-blocked-by-the-authenticated-user) [List users blocked by an organization](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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) if ($OrganizationName) { Get-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -PerPage $PerPage } else { Get-GitHubBlockedUserByUser -PerPage $PerPage } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser] - Done" #endregion - From [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser] #region - From [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser] - 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 [Check if a user is blocked by the authenticated user](https://docs.github.com/rest/users/blocking#check-if-a-user-is-blocked-by-the-authenticated-user) [Check if a user is blocked by an organization](https://docs.github.com/rest/orgs/blocking#check-if-a-user-is-blocked-by-an-organization) #> [OutputType([bool])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [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')] [string] $OrganizationName, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) if ($OrganizationName) { Test-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -Username $Username -PerPage $PerPage } else { Test-GitHubBlockedUserByUser -Username $Username -PerPage $PerPage } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser] - Done" #endregion - From [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser] #region - From [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser] - 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 [Unblock a user](https://docs.github.com/rest/users/blocking#unblock-a-user) [Unblock a user from an organization](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')] [string] $OrganizationName ) if ($OrganizationName) { Unblock-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username } else { Unblock-GitHubUserByUser -Username $Username } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser] - Done" #endregion - From [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - Done" #endregion - From [functions] - [public] - [Users] - [Blocking] #region - From [functions] - [public] - [Users] - [Emails] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - Processing folder" #region - From [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail] - 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 [Add an email address for the authenticated user](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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail] - Done" #endregion - From [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail] #region - From [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail] - 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 [List email addresses for the authenticated user](https://docs.github.com/rest/users/emails#list-email-addresses-for-the-authenticated-user) [List public email addresses for the authenticated user](https://docs.github.com/en/rest/users/emails#list-public-email-addresses-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding()] param ( # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30, [Parameter()] [switch] $Public ) if ($Public) { Get-GitHubUserPublicEmail -PerPage $PerPage } else { Get-GitHubUserAllEmail -PerPage $PerPage } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail] - Done" #endregion - From [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail] #region - From [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail] - 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 [Delete an email address for the authenticated user](https://docs.github.com/rest/users/emails#delete-an-email-address-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] 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 } if ($PSCmdlet.ShouldProcess("Email addresses [$($Emails -join ', ')]", 'Delete')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail] - Done" #endregion - From [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail] #region - From [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility] - 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 [Set primary email visibility for the authenticated user](https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] 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 } if ($PSCmdlet.ShouldProcess("Email visibility [$Visibility]", 'Set')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility] - Done" #endregion - From [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - Done" #endregion - From [functions] - [public] - [Users] - [Emails] #region - From [functions] - [public] - [Users] - [Followers] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - Processing folder" #region - From [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing] - 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 [Follow a user](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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing] - Done" #endregion - From [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing] #region - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower] - Importing" filter Get-GitHubUserFollower { <# .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-GitHubUserFollower Gets all followers of the authenticated user. .EXAMPLE Get-GitHubUserFollower -Username 'octocat' Gets all followers of the user 'octocat'. .NOTES [List followers of the authenticated user](https://docs.github.com/rest/users/followers#list-followers-of-the-authenticated-user) #> [OutputType([pscustomobject])] [Alias('Get-GitHubUserMyFollowers')] [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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserFollowersOfUser -Username $Username -PerPage $PerPage } else { Get-GitHubUserMyFollowers -PerPage $PerPage } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower] - Done" #endregion - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower] #region - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing] - 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 [List the people the authenticated user follows](https://docs.github.com/rest/users/followers#list-the-people-the-authenticated-user-follows) [List the people a 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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserFollowingUser -Username $Username -PerPage $PerPage } else { Get-GitHubUserFollowingMe -PerPage $PerPage } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing] - Done" #endregion - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing] #region - From [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing] - 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 [Unfollow a user](https://docs.github.com/rest/users/followers#unfollow-a-user) #> [OutputType([pscustomobject])] [Alias('Unfollow-GitHubUser')] [CmdletBinding(SupportsShouldProcess)] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName )] [string] $Username ) $inputObject = @{ APIEndpoint = "/user/following/$Username" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("User [$Username]", 'Unfollow')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing] - Done" #endregion - From [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing] #region - From [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing] - Importing" filter Test-GitHubUserFollowing { <# .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-GitHubUserFollowing -Follows 'octocat' Test-GitHubUserFollowing 'octocat' Checks if the authenticated user follows the user 'octocat'. .EXAMPLE Test-GitHubUserFollowing -Username 'octocat' -Follows 'ratstallion' Checks if the user 'octocat' follows the user 'ratstallion'. .NOTES [Check if a person is followed by the authenticated user](https://docs.github.com/rest/users/followers#check-if-a-person-is-followed-by-the-authenticated-user) [Check if a user follows another user](https://docs.github.com/rest/users/followers#check-if-a-user-follows-another-user) #> [OutputType([bool])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [Alias('Test-GitHubUserFollows')] [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] - [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing] - Done" #endregion - From [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - Done" #endregion - From [functions] - [public] - [Users] - [Followers] #region - From [functions] - [public] - [Users] - [GPG-Keys] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - Processing folder" #region - From [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey] - 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----- Version: GnuPG v1 mQINBFnZ2ZIBEADQ2Z7Z7 -----END PGP PUBLIC KEY BLOCK----- '@ Adds a GPG key to the authenticated user's GitHub account. .NOTES [Create a GPG key for the authenticated user](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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey] - Done" #endregion - From [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey] #region - From [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey] - 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 -ID '1234567' Gets the GPG key with ID '1234567' for the authenticated user. .EXAMPLE Get-GitHubUserGpgKey -Username 'octocat' Gets all GPG keys for the 'octocat' user. .NOTES [List GPG keys for the authenticated user](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()] [ValidateRange(1, 100)] [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] - [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey] - Done" #endregion - From [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey] #region - From [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey] - 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 [Delete a GPG key for the authenticated user](https://docs.github.com/rest/users/gpg-keys#delete-a-gpg-key-for-the-authenticated-user) #> [OutputType([pscustomobject])] [CmdletBinding(SupportsShouldProcess)] param ( # The ID of the GPG key. [Parameter( Mandatory )] [Alias('gpg_key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/gpg_keys/$ID" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("GPG key with ID [$ID]", 'Delete')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey] - Done" #endregion - From [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - Done" #endregion - From [functions] - [public] - [Users] - [GPG-Keys] #region - From [functions] - [public] - [Users] - [Keys] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - Processing folder" #region - From [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey] - Importing" filter Add-GitHubUserKey { <# .SYNOPSIS Create a public SSH key for the authenticated user .DESCRIPTION Adds a public SSH key to the authenticated user's GitHub account. Requires that you are authenticated via Basic Auth, or OAuth with at least `write:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Add-GitHubUserKey -Title 'ssh-rsa AAAAB3NzaC1yc2EAAA' -Key '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234' Adds a new public SSH key to the authenticated user's GitHub account. .NOTES [Create a public SSH key for the authenticated user](https://docs.github.com/rest/users/keys#create-a-public-ssh-key-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')] [CmdletBinding()] param ( # A descriptive name for the new key. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('name')] [string] $Title, # The public SSH key to add to your GitHub account. [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Key ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/keys' Method = 'POST' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey] - Done" #endregion - From [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey] #region - From [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey] - Importing" filter Get-GitHubUserKey { <# .SYNOPSIS List public SSH keys for a given user or the authenticated user. .DESCRIPTION Lists a given user's or the current user's public SSH keys. For the authenticated users keys, it requires that you are authenticated via Basic Auth or via OAuth with at least `read:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). Keys from a given user are accessible by anyone. .EXAMPLE Get-GitHubUserKey Gets all GPG keys for the authenticated user. .EXAMPLE Get-GitHubUserKey -ID '1234567' Gets the public SSH key with the ID '1234567' for the authenticated user. .EXAMPLE Get-GitHubUserKey -Username 'octocat' Gets all GPG keys for the 'octocat' user. .NOTES [List GPG keys for the authenticated user](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()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserKeyForUser -Username $Username -PerPage $PerPage } else { if ($ID) { Get-GitHubUserMyKeyById -ID $ID } else { Get-GitHubUserMyKey -PerPage $PerPage } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey] - Done" #endregion - From [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey] #region - From [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey] - Importing" filter Remove-GitHubUserKey { <# .SYNOPSIS Delete a public SSH key for the authenticated user .DESCRIPTION Removes a public SSH key from the authenticated user's GitHub account. Requires that you are authenticated via Basic Auth or via OAuth with at least `admin:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/). .EXAMPLE Remove-GitHubUserKey -ID '1234567' Deletes the public SSH key with ID '1234567' from the authenticated user's GitHub account. .NOTES [Delete a public SSH key for the authenticated user](https://docs.github.com/rest/users/keys#delete-a-public-ssh-key-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] param ( # The unique identifier of the key. [Parameter( Mandatory )] [Alias('key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/keys/$ID" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("Key with ID [$ID]", 'Delete')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey] - Done" #endregion - From [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - Done" #endregion - From [functions] - [public] - [Users] - [Keys] #region - From [functions] - [public] - [Users] - [Social-Accounts] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - Processing folder" #region - From [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial] - Importing" filter Add-GitHubUserSocial { <# .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-GitHubUserSocial -AccountUrls 'https://twitter.com/MyTwitterAccount', 'https://www.linkedin.com/company/MyCompany' Adds the Twitter and LinkedIn accounts to the authenticated user's profile. .NOTES [Add social accounts for the authenticated user](https://docs.github.com/rest/users/social-accounts#add-social-accounts-for-the-authenticated-user) #> [OutputType([void])] [Alias('Add-GitHubUserSocials')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')] [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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial] - Done" #endregion - From [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial] #region - From [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial] - Importing" filter Remove-GitHubUserSocial { <# .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-GitHubUserSocial -AccountUrls 'https://twitter.com/MyTwitterAccount' .NOTES [Delete social accounts for the authenticated user](https://docs.github.com/rest/users/social-accounts#delete-social-accounts-for-the-authenticated-user) #> [OutputType([void])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [Alias('Remove-GitHubUserSocials')] [CmdletBinding(SupportsShouldProcess)] 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' } if ($PSCmdlet.ShouldProcess("Social accounts [$($AccountUrls -join ', ')]", 'Delete')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial] - Done" #endregion - From [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - Done" #endregion - From [functions] - [public] - [Users] - [Social-Accounts] #region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - Processing folder" #region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey] - Importing" filter Add-GitHubUserSigningKey { <# .SYNOPSIS Create a SSH signing key for the authenticated user .DESCRIPTION Creates an SSH signing key for the authenticated user's GitHub account. You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `write:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)." .EXAMPLE Add-GitHubUserSigningKey -Title 'ssh-rsa AAAAB3NzaC1yc2EAAA' -Key '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234' Creates a new SSH signing key for the authenticated user's GitHub account. .NOTES [Create a SSH signing key for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#create-a-ssh-signing-key-for-the-authenticated-user) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')] [OutputType([pscustomobject])] [CmdletBinding()] param ( # A descriptive name for the new key. [Parameter( ValueFromPipeline, ValueFromPipelineByPropertyName )] [Alias('name')] [string] $Title, # The public SSH key to add to your GitHub account. For more information, see # [Checking for existing SSH keys](https://docs.github.com/authentication/connecting-to-github-with-ssh/checking-for-existing-ssh-keys)." [Parameter( Mandatory, ValueFromPipelineByPropertyName )] [string] $Key ) $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case $inputObject = @{ APIEndpoint = '/user/ssh_signing_keys' Method = 'POST' Body = $body } Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey] - Done" #endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey] #region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey] - Importing" filter Get-GitHubUserSigningKey { <# .SYNOPSIS List SSH signing keys for a given user or the authenticated user. .DESCRIPTION Lists a given user's or the current user's SSH signing keys. .EXAMPLE Get-GitHubUserSigningKey Gets all SSH signing keys for the authenticated user. .EXAMPLE Get-GitHubUserSigningKey -ID '1234567' Gets the SSH signing key with the ID '1234567' for the authenticated user. .EXAMPLE Get-GitHubUserSigningKey -Username 'octocat' Gets all SSH signing keys for the 'octocat' user. .NOTES [List SSH signing keys for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-the-authenticated-user) [Get an SSH signing key for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#get-an-ssh-signing-key-for-the-authenticated-user) [List SSH signing keys for a user](https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-a-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding()] param ( # The handle for the GitHub user account. [Parameter( Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'Username' )] [string] $Username, # The unique identifier of the SSH signing key. [Parameter( ParameterSetName = 'Me' )] [Alias('gpg_key_id')] [string] $ID, # The number of results per page (max 100). [Parameter()] [ValidateRange(1, 100)] [int] $PerPage = 30 ) if ($Username) { Get-GitHubUserSigningKeyForUser -Username $Username -PerPage $PerPage } else { if ($ID) { Get-GitHubUserMySigningKeyById -ID $ID } else { Get-GitHubUserMySigningKey -PerPage $PerPage } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey] - Done" #endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey] #region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey] - Importing" filter Remove-GitHubUserSigningKey { <# .SYNOPSIS Delete an SSH signing key for the authenticated user .DESCRIPTION Deletes an SSH signing key from the authenticated user's GitHub account. You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `admin:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)." .EXAMPLE Remove-GitHubUserSigningKey -ID '1234567' Removes the SSH signing key with the ID of `1234567` from the authenticated user's GitHub account. .NOTES [Delete an SSH signing key for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#delete-an-ssh-signing-key-for-the-authenticated-user) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')] [CmdletBinding(SupportsShouldProcess)] param ( # The unique identifier of the SSH signing key. [Parameter( Mandatory )] [Alias('ssh_signing_key_id')] [string] $ID ) $inputObject = @{ APIEndpoint = "/user/ssh_signing_keys/$ID" Method = 'DELETE' } if ($PSCmdlet.ShouldProcess("SSH signing key with ID [$ID]", 'Delete')) { $null = Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey] - Done" #endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - Done" #endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] #region - From [functions] - [public] - [Users] - [Get-GitHubUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Get-GitHubUser] - 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 [Get the authenticated user](https://docs.github.com/rest/users/users) #> [OutputType([pscustomobject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSReviewUnusedParameter', 'All', Justification = 'Parameter is used in dynamic parameter validation.' )] [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')] [ValidateRange(1, 100)] [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] - [functions] - [public] - [Users] - [Get-GitHubUser] - Done" #endregion - From [functions] - [public] - [Users] - [Get-GitHubUser] #region - From [functions] - [public] - [Users] - [Get-GitHubUserCard] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Get-GitHubUserCard] - 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 [Get contextual information for a user](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 | ForEach-Object { Write-Output $_.Response } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Get-GitHubUserCard] - Done" #endregion - From [functions] - [public] - [Users] - [Get-GitHubUserCard] #region - From [functions] - [public] - [Users] - [Set-GitHubUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Set-GitHubUser] - 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 [Update the authenticated user](https://docs.github.com/rest/users/users#update-the-authenticated-user) #> [OutputType([void])] [Alias('Update-GitHubUser')] [CmdletBinding(SupportsShouldProcess)] 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' } if ($PSCmdlet.ShouldProcess('authenticated user', 'Set')) { Invoke-GitHubAPI @inputObject | ForEach-Object { Write-Output $_.Response } } } Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Set-GitHubUser] - Done" #endregion - From [functions] - [public] - [Users] - [Set-GitHubUser] Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - Done" #endregion - From [functions] - [public] - [Users] Write-Verbose "[$scriptName] - [functions] - [public] - Done" #endregion - From [functions] - [public] #region - From [variables] - [private] Write-Verbose "[$scriptName] - [variables] - [private] - Processing folder" #region - From [variables] - [private] - [Auth] Write-Verbose "[$scriptName] - [variables] - [private] - [Auth] - Importing" $script:Auth = @{ GitHubApp = @{ ClientID = 'Iv1.f26b61bc99e69405' # $script:Auth.GitHubApp.ClientID #gitleaks:allow } OAuthApp = @{ ClientID = '7204ae9b0580f2cb8288' # $script:Auth.OAuthApp.ClientID #gitleaks:allow } AccessTokenGracePeriodInHours = 4 } Write-Verbose "[$scriptName] - [variables] - [private] - [Auth] - Done" #endregion - From [variables] - [private] - [Auth] #region - From [variables] - [private] - [Config] Write-Verbose "[$scriptName] - [variables] - [private] - [Config] - Importing" $script:Config = @{ Name = 'PSModule.GitHub' # $script:Config.Name } Write-Verbose "[$scriptName] - [variables] - [private] - [Config] - Done" #endregion - From [variables] - [private] - [Config] Write-Verbose "[$scriptName] - [variables] - [private] - Done" #endregion - From [variables] - [private] #region - From [completers] Write-Verbose "[$scriptName] - [completers] - Importing" Register-ArgumentCompleter -ParameterName Context -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter $contexts = Get-GitHubContext -ListAvailable -Verbose:$false | Where-Object { "$($_.HostName)/$($_.UserName)" -like "$wordToComplete*" } $contexts | ForEach-Object { $contextID = "$($_.HostName)/$($_.UserName)" [System.Management.Automation.CompletionResult]::new($contextID, $contextID, 'ParameterValue', $contextID) } } Write-Verbose "[$scriptName] - [completers] - Done" #endregion - From [completers] #region - From [loader] Write-Verbose "[$scriptName] - [loader] - Importing" $scriptFilePath = $MyInvocation.MyCommand.Path Write-Verbose 'Initializing GitHub PowerShell module...' Write-Verbose "Path: $scriptFilePath" $script:runEnv = if ($env:GITHUB_ACTIONS -eq 'true') { 'GHA' } elseif (-not [string]::IsNullOrEmpty($env:WEBSITE_PLATFORM_VERSION)) { 'AFA' } else { 'Local' } if ($env:GITHUB_ACTIONS -eq 'true') { Write-Verbose 'Detected running on a GitHub Actions runner, preparing environment...' $env:GITHUB_REPOSITORY_NAME = $env:GITHUB_REPOSITORY -replace '.+/' Set-GitHubEnv -Name 'GITHUB_REPOSITORY_NAME' -Value $env:GITHUB_REPOSITORY_NAME } ### This is the context for this module # Get current module context $context = (Get-Context -ID $script:Config.Name) if (-not $context) { Write-Verbose 'No context found, creating a new context...' Set-Context -ID $script:Config.Name -Context @{ Name = 'GitHub' RunEnv = $script:runEnv } } Write-Verbose "[$scriptName] - [loader] - Done" #endregion - From [loader] # Get the internal TypeAccelerators class to use its static methods. $TypeAcceleratorsClass = [psobject].Assembly.GetType( 'System.Management.Automation.TypeAccelerators' ) # Ensure none of the types would clobber an existing type accelerator. # If a type accelerator with the same name exists, throw an exception. $ExistingTypeAccelerators = $TypeAcceleratorsClass::Get # Define the types to export with type accelerators. $ExportableEnums = @( ) $ExportableEnums | Foreach-Object { Write-Verbose "Exporting enum '$($_.FullName)'." } foreach ($Type in $ExportableEnums) { if ($Type.FullName -in $ExistingTypeAccelerators.Keys) { Write-Warning "Enum already exists [$($Type.FullName)]. Skipping." } else { Write-Verbose "Importing enum '$Type'." $TypeAcceleratorsClass::Add($Type.FullName, $Type) } } $ExportableClasses = @( [GitHubContext] ) $ExportableClasses | Foreach-Object { Write-Verbose "Exporting class '$($_.FullName)'." } foreach ($Type in $ExportableClasses) { if ($Type.FullName -in $ExistingTypeAccelerators.Keys) { Write-Warning "Class already exists [$($Type.FullName)]. Skipping." } else { Write-Verbose "Importing class '$Type'." $TypeAcceleratorsClass::Add($Type.FullName, $Type) } } # Remove type accelerators when the module is removed. $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { foreach ($Type in ($ExportableEnums + $ExportableClasses)) { $TypeAcceleratorsClass::Remove($Type.FullName) } }.GetNewClosure() $exports = @{ Alias = '*' Cmdlet = '' Function = @( 'Disable-GitHubWorkflow' 'Enable-GitHubWorkflow' 'Get-GitHubWorkflow' 'Get-GitHubWorkflowRun' 'Get-GitHubWorkflowUsage' 'Remove-GitHubWorkflowRun' 'Start-GitHubWorkflow' 'Start-GitHubWorkflowReRun' 'Stop-GitHubWorkflowRun' 'Invoke-GitHubAPI' 'Get-GitHubApp' 'Get-GitHubAppInstallation' 'Get-GitHubAppJSONWebToken' 'New-GitHubAppInstallationAccessToken' 'Get-GitHubContext' 'Remove-GitHubContext' 'Set-GitHubContext' 'Set-GitHubDefaultContext' 'Get-GitHubContextSetting' 'Set-GitHubContextSetting' 'Connect-GitHubAccount' 'Disconnect-GitHubAccount' 'Get-GitHubViewer' 'Get-GitHubRepoBranch' 'Add-GitHubMask' 'Add-GitHubSystemPath' 'Disable-GitHubCommand' 'Enable-GitHubCommand' 'Get-GitHubOutput' 'Set-GitHubEnvironmentVariable' 'Set-GitHubLogGroup' 'Set-GitHubNoCommandGroup' 'Set-GitHubOutput' 'Set-GitHubStepSummary' 'Start-GitHubLogGroup' 'Stop-GitHubLogGroup' 'Write-GitHubDebug' 'Write-GitHubError' 'Write-GitHubNotice' 'Write-GitHubWarning' 'Get-GitHubConfig' 'Remove-GitHubConfig' 'Set-GitHubConfig' 'Get-GitHubEmoji' 'Get-GitHubEnterpriseInstallableOrganization' 'Get-GitHubEnterpriseOrganization' 'Install-GitHubAppOnEnterpriseOrganization' 'Get-GitHubGitConfig' 'Set-GitHubGitConfig' 'Get-GitHubGitignore' 'Invoke-GitHubGraphQLQuery' 'Get-GitHubLicense' 'Get-GitHubMarkdown' 'Get-GitHubMarkdownRaw' 'Get-GitHubApiVersion' 'Get-GitHubMeta' 'Get-GitHubOctocat' 'Get-GitHubRoot' 'Get-GitHubZen' 'Get-GitHubOrganizationMember' 'Get-GitHubOrganizationPendingInvitation' 'New-GitHubOrganizationInvitation' 'Get-GitHubOrganization' 'Get-GitHubOrganizationAppInstallation' 'Remove-GitHubOrganization' 'Set-GitHubOrganization' 'Set-GitHubOrganizationSecurityFeature' 'Get-GitHubRateLimit' 'Add-GitHubReleaseAsset' 'Get-GitHubReleaseAsset' 'Remove-GitHubReleaseAsset' 'Set-GitHubReleaseAsset' 'Get-GitHubRelease' 'New-GitHubRelease' 'New-GitHubReleaseNote' 'Remove-GitHubRelease' 'Set-GitHubRelease' 'Get-GitHubRepositoryAutolink' 'New-GitHubRepositoryAutolink' 'Remove-GitHubRepositoryAutolink' 'Get-GitHubRepositoryCustomProperty' 'Disable-GitHubRepositoryPrivateVulnerabilityReporting' 'Disable-GitHubRepositorySecurityFix' 'Disable-GitHubRepositoryVulnerabilityAlert' 'Enable-GitHubRepositoryPrivateVulnerabilityReporting' 'Enable-GitHubRepositorySecurityFix' 'Enable-GitHubRepositoryVulnerabilityAlert' 'Get-GitHubRepository' 'Get-GitHubRepositoryActivity' 'Get-GitHubRepositoryCodeownersError' 'Get-GitHubRepositoryContributor' 'Get-GitHubRepositoryFork' 'Get-GitHubRepositoryLanguage' 'Get-GitHubRepositorySecurityFix' 'Get-GitHubRepositoryTag' 'Get-GitHubRepositoryTeam' 'Get-GitHubRepositoryTopic' 'Move-GitHubRepository' 'New-GitHubRepository' 'Remove-GitHubRepository' 'Set-GitHubRepositoryTopic' 'Start-GitHubRepositoryEvent' 'Test-GitHubRepositoryVulnerabilityAlert' 'Update-GitHubRepository' 'Get-GitHubRepositoryRuleSuite' 'Get-GitHubRepositoryRuleSuiteById' 'Get-GitHubRepositoryRuleSuiteList' 'Get-GitHubRepositoryTagProtection' 'New-GitHubRepositoryTagProtection' 'Remove-GitHubRepositoryTagProtection' 'Get-GitHubScheduledMaintenance' 'Get-GitHubStatus' 'Get-GitHubStatusComponent' 'Get-GitHubStatusIncident' 'Get-GitHubRepoTeam' 'Get-GitHubTeamByName' 'Get-GitHubTeamListByOrg' 'New-GitHubTeam' 'Remove-GitHubTeam' 'Update-GitHubTeam' 'Block-GitHubUser' 'Get-GitHubBlockedUser' 'Test-GitHubBlockedUser' 'Unblock-GitHubUser' 'Add-GitHubUserEmail' 'Get-GitHubUserEmail' 'Remove-GitHubUserEmail' 'Set-GitHubUserEmailVisibility' 'Add-GitHubUserFollowing' 'Get-GitHubUserFollower' 'Get-GitHubUserFollowing' 'Remove-GitHubUserFollowing' 'Test-GitHubUserFollowing' 'Add-GitHubUserGpgKey' 'Get-GitHubUserGpgKey' 'Remove-GitHubUserGpgKey' 'Add-GitHubUserKey' 'Get-GitHubUserKey' 'Remove-GitHubUserKey' 'Add-GitHubUserSocial' 'Remove-GitHubUserSocial' 'Add-GitHubUserSigningKey' 'Get-GitHubUserSigningKey' 'Remove-GitHubUserSigningKey' 'Get-GitHubUser' 'Get-GitHubUserCard' 'Set-GitHubUser' ) } Export-ModuleMember @exports |