diff --git a/Formatters/GitHubGistComments.Format.ps1xml b/Formatters/GitHubGistComments.Format.ps1xml
new file mode 100644
index 00000000..b2035fca
--- /dev/null
+++ b/Formatters/GitHubGistComments.Format.ps1xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<Configuration>
+  <ViewDefinitions>
+    <!--================== GitHub.GistComment Type View =================-->
+    <View>
+      <Name>GitHub.GistComment</Name>
+      <ViewSelectedBy>
+        <TypeName>GitHub.GistComment</TypeName>
+      </ViewSelectedBy>
+      <TableControl>
+        <TableHeaders>
+          <TableColumnHeader>
+            <Label>ID</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>User</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Comment</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Created</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Updated</Label>
+          </TableColumnHeader>
+        </TableHeaders>
+        <TableRowEntries>
+          <TableRowEntry>
+            <TableColumnItems>
+              <TableColumnItem>
+                <PropertyName>id</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  $_.user.login
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>body</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>created_at</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>updated_at</PropertyName>
+              </TableColumnItem>
+            </TableColumnItems>
+          </TableRowEntry>
+        </TableRowEntries>
+      </TableControl>
+    </View>
+  </ViewDefinitions>
+</Configuration>
diff --git a/Formatters/GitHubGists.Format.ps1xml b/Formatters/GitHubGists.Format.ps1xml
new file mode 100644
index 00000000..3e02fa85
--- /dev/null
+++ b/Formatters/GitHubGists.Format.ps1xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<Configuration>
+  <ViewDefinitions>
+    <!--================== GitHub.Gist Type View =================-->
+    <View>
+      <Name>GitHub.Gist</Name>
+      <ViewSelectedBy>
+        <TypeName>GitHub.Gist</TypeName>
+      </ViewSelectedBy>
+      <TableControl>
+        <TableHeaders>
+          <TableColumnHeader>
+            <Label>ID</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>User</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Description</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Public</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Files</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Created</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Updated</Label>
+          </TableColumnHeader>
+        </TableHeaders>
+        <TableRowEntries>
+          <TableRowEntry>
+            <TableColumnItems>
+              <TableColumnItem>
+                <PropertyName>id</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  $_.owner.login
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>description</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>public</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  ($_.files |
+                    Get-Member -MemberType NoteProperty |
+                    Select-Object -ExpandProperty Name) -join ', '
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>created_at</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>updated_at</PropertyName>
+              </TableColumnItem>
+            </TableColumnItems>
+          </TableRowEntry>
+        </TableRowEntries>
+      </TableControl>
+    </View>
+    <!--=============== GitHub.GistCommit Type View ===============-->
+    <View>
+      <Name>GitHub.GistCommit</Name>
+      <ViewSelectedBy>
+        <TypeName>GitHub.GistCommit</TypeName>
+      </ViewSelectedBy>
+      <TableControl>
+        <TableHeaders>
+          <TableColumnHeader>
+            <Label>ID</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Sha</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>User</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Committed</Label>
+          </TableColumnHeader>
+        </TableHeaders>
+        <TableRowEntries>
+          <TableRowEntry>
+            <TableColumnItems>
+              <TableColumnItem>
+                <PropertyName>GistId</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>version</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  ($_.user.login)
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>committed_at</PropertyName>
+              </TableColumnItem>
+            </TableColumnItems>
+          </TableRowEntry>
+        </TableRowEntries>
+      </TableControl>
+    </View>
+    <!--================== GitHub.GistDetail Type View =================-->
+    <View>
+      <Name>GitHub.GistDetail</Name>
+      <ViewSelectedBy>
+        <TypeName>GitHub.GistDetail</TypeName>
+      </ViewSelectedBy>
+      <TableControl>
+        <TableHeaders>
+          <TableColumnHeader>
+            <Label>ID</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>owner</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Description</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Public</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Files</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Forks</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Created</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Updated</Label>
+          </TableColumnHeader>
+        </TableHeaders>
+        <TableRowEntries>
+          <TableRowEntry>
+            <TableColumnItems>
+              <TableColumnItem>
+                <PropertyName>id</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  ($_.owner.login)
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>description</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>public</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  ($_.files |
+                    Get-Member -MemberType NoteProperty |
+                    Select-Object -ExpandProperty Name) -join ', '
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  ($_.forks.Count)
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>created_at</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>updated_at</PropertyName>
+              </TableColumnItem>
+            </TableColumnItems>
+          </TableRowEntry>
+        </TableRowEntries>
+      </TableControl>
+    </View>
+    <!--=============== GitHub.GistFork Type View ===============-->
+    <View>
+      <Name>GitHub.GistFork</Name>
+      <ViewSelectedBy>
+        <TypeName>GitHub.GistFork</TypeName>
+      </ViewSelectedBy>
+      <TableControl>
+        <TableHeaders>
+          <TableColumnHeader>
+            <Label>ID</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>User</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Created</Label>
+          </TableColumnHeader>
+          <TableColumnHeader>
+            <Label>Updated</Label>
+          </TableColumnHeader>
+        </TableHeaders>
+        <TableRowEntries>
+          <TableRowEntry>
+            <TableColumnItems>
+              <TableColumnItem>
+                <PropertyName>id</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <ScriptBlock>
+                  # There appears to be a bug in the GitHub API.
+                  # Documentation says that the property should alway be "user",
+                  # but it switches between "owner" and "user" depending on if it's a property
+                  # of a gist, or the direct result from a gist forks query.
+                  # https://github.community/t/gist-api-v3-documentation-incorrect-for-forks/122545
+                  if ($null -eq $_.user)
+                  {
+                     $_.owner.login
+                  }
+                  else
+                  {
+                     $_.user.login
+                  }
+                </ScriptBlock>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>created_at</PropertyName>
+              </TableColumnItem>
+              <TableColumnItem>
+                <PropertyName>updated_at</PropertyName>
+              </TableColumnItem>
+            </TableColumnItems>
+          </TableRowEntry>
+        </TableRowEntries>
+      </TableControl>
+    </View>
+  </ViewDefinitions>
+</Configuration>
diff --git a/GitHubCore.ps1 b/GitHubCore.ps1
index 02c887fd..4ea6fabd 100644
--- a/GitHubCore.ps1
+++ b/GitHubCore.ps1
@@ -329,6 +329,15 @@ function Invoke-GHRestMethod
                 $finalResult = $finalResult | ConvertFrom-Json
             }
         }
+        catch [InvalidOperationException]
+        {
+            # In some cases, the returned data might have two different keys of the same characters
+            # but different casing (this can happen with gists with two files named 'a.txt' and 'A.txt').
+            # PowerShell 6 introduced the -AsHashtable switch to work around this issue, but this
+            # module wants to be compatible down to PowerShell 4, so we're unable to use that feature.
+            Write-Log -Message 'The returned object likely contains keys that differ only in casing.  Unable to convert to an object.  Returning the raw JSON as a fallback.' -Level Warning
+            $finalResult = $finalResult
+        }
         catch [ArgumentException]
         {
             # The content must not be JSON (which is a legitimate situation).
diff --git a/GitHubGistComments.ps1 b/GitHubGistComments.ps1
new file mode 100644
index 00000000..b8d43b31
--- /dev/null
+++ b/GitHubGistComments.ps1
@@ -0,0 +1,495 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+@{
+    GitHubGistCommentTypeName = 'GitHub.GistComment'
+ }.GetEnumerator() | ForEach-Object {
+     Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value
+ }
+
+filter Get-GitHubGistComment
+{
+<#
+    .SYNOPSIS
+        Retrieves comments for a specific gist from GitHub.
+
+    .DESCRIPTION
+        Retrieves comments for a specific gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to retrieve the comments for.
+
+    .PARAMETER Comment
+        The ID of the specific comment on the gist that you wish to retrieve.
+
+    .PARAMETER MediaType
+        The format in which the API will return the body of the comment.
+
+        Raw - Return the raw markdown body. Response will include body. This is the default if you do not pass any specific media type.
+        Text - Return a text only representation of the markdown body. Response will include body_text.
+        Html - Return HTML rendered from the body's markdown. Response will include body_html.
+        Full - Return raw, text and HTML representations. Response will include body, body_text, and body_html.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.GistComment
+
+    .EXAMPLE
+        Get-GitHubGistComment -Gist 6cad326836d38bd3a7ae
+
+        Gets all comments on octocat's "hello_world.rb" gist.
+
+    .EXAMPLE
+        Get-GitHubGistComment -Gist 6cad326836d38bd3a7ae -Comment 1507813
+
+        Gets comment 1507813 from octocat's "hello_world.rb" gist.
+#>
+    [CmdletBinding(PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistCommentTypeName})]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [string] $Gist,
+
+        [Parameter(ValueFromPipelineByPropertyName)]
+        [Alias('GistCommentId')]
+        [ValidateNotNullOrEmpty()]
+        [int64] $Comment,
+
+        [ValidateSet('Raw', 'Text', 'Html', 'Full')]
+        [string] $MediaType = 'Full',
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    $telemetryProperties = @{}
+
+    $uriFragment = [String]::Empty
+    $description = [String]::Empty
+
+    if ($PSBoundParameters.ContainsKey('Comment'))
+    {
+        $telemetryProperties['SpecifiedComment'] = $true
+
+        $uriFragment = "gists/$Gist/comments/$Comment"
+        $description = "Getting comment $Comment for gist $Gist"
+    }
+    else
+    {
+        $uriFragment = "gists/$Gist/comments"
+        $description = "Getting comments for gist $Gist"
+    }
+
+    $params = @{
+        'UriFragment' = $uriFragment
+        'Description' =  $description
+        'AccessToken' = $AccessToken
+        'AcceptHeader' = (Get-MediaAcceptHeader -MediaType $MediaType -AsJson)
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return (Invoke-GHRestMethodMultipleResult @params | Add-GitHubGistCommentAdditionalProperties)
+}
+
+filter Remove-GitHubGistComment
+{
+<#
+    .SYNOPSIS
+        Removes/deletes a comment from a gist on GitHub.
+
+    .DESCRIPTION
+        Removes/deletes a comment from a gist on GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to remove the comment from.
+
+    .PARAMETER Comment
+        The ID of the comment to remove from the gist.
+
+    .PARAMETER Force
+        If this switch is specified, you will not be prompted for confirmation of command execution.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Remove-GitHubGist -Gist 6cad326836d38bd3a7ae -Comment 12324567
+
+        Removes the specified comment from octocat's "hello_world.rb" gist
+        (assuming you have permission).
+
+    .EXAMPLE
+        Remove-GitHubGist -Gist 6cad326836d38bd3a7ae -Comment 12324567 -Confirm:$false
+
+        Removes the specified comment from octocat's "hello_world.rb" gist
+        (assuming you have permission).
+        Will not prompt for confirmation, as -Confirm:$false was specified.
+
+    .EXAMPLE
+        Remove-GitHubGist -Gist 6cad326836d38bd3a7ae -Comment 12324567 -Force
+
+        Removes the specified comment from octocat's "hello_world.rb" gist
+        (assuming you have permission).
+        Will not prompt for confirmation, as -Force was specified.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false,
+        ConfirmImpact="High")]
+    [Alias('Delete-GitHubGist')]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 2)]
+        [Alias('GistCommentId')]
+        [ValidateNotNullOrEmpty()]
+        [int64] $Comment,
+
+        [switch] $Force,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    if ($Force -and (-not $Confirm))
+    {
+        $ConfirmPreference = 'None'
+    }
+
+    if (-not $PSCmdlet.ShouldProcess($Comment, "Delete comment from gist $Gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/comments/$Comment"
+        'Method' = 'Delete'
+        'Description' =  "Removing comment $Comment from gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return Invoke-GHRestMethod @params
+}
+
+filter New-GitHubGistComment
+{
+<#
+    .SYNOPSIS
+        Creates a new comment on the specified gist from GitHub.
+
+    .DESCRIPTION
+        Creates a new comment on the specified gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to add the comment to.
+
+    .PARAMETER Body
+        The body of the comment that you wish to leave on the gist.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.GistComment
+
+    .EXAMPLE
+        New-GitHubGistComment -Gist 6cad326836d38bd3a7ae -Body 'Hello World'
+
+        Adds a new comment of "Hello World" to octocat's "hello_world.rb" gist.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistCommentTypeName})]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(
+            Mandatory,
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string] $Body,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    $hashBody = @{
+        'body' = $Body
+    }
+
+    if (-not $PSCmdlet.ShouldProcess($Gist, "Create new comment for gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/comments"
+        'Body' = (ConvertTo-Json -InputObject $hashBody)
+        'Method' = 'Post'
+        'Description' =  "Creating new comment on gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return (Invoke-GHRestMethod @params | Add-GitHubGistCommentAdditionalProperties)
+}
+
+filter Set-GitHubGistComment
+{
+    <#
+    .SYNOPSIS
+        Edits a comment on the specified gist from GitHub.
+
+    .DESCRIPTION
+        Edits a comment on the specified gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the gist that the comment is on.
+
+    .PARAMETER Comment
+        The ID of the comment that you wish to edit.
+
+    .PARAMETER Body
+        The new text of the comment that you wish to leave on the gist.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.GistComment
+
+    .EXAMPLE
+        New-GitHubGistComment -Gist 6cad326836d38bd3a7ae -Comment 1232456 -Body 'Hello World'
+
+        Updates the body of the comment with ID 1232456 octocat's "hello_world.rb" gist to be
+        "Hello World".
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistCommentTypeName})]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 2)]
+        [Alias('GistCommentId')]
+        [ValidateNotNullOrEmpty()]
+        [int64] $Comment,
+
+        [Parameter(
+            Mandatory,
+            Position = 3)]
+        [ValidateNotNullOrEmpty()]
+        [string] $Body,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    $hashBody = @{
+        'body' = $Body
+    }
+
+    if (-not $PSCmdlet.ShouldProcess($Comment, "Update gist comment on gist $Gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/comments/$Comment"
+        'Body' = (ConvertTo-Json -InputObject $hashBody)
+        'Method' = 'Patch'
+        'Description' = "Creating new comment on gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return (Invoke-GHRestMethod @params | Add-GitHubGistCommentAdditionalProperties)
+}
+
+filter Add-GitHubGistCommentAdditionalProperties
+{
+<#
+    .SYNOPSIS
+        Adds type name and additional properties to ease pipelining to GitHub Gist Comment objects.
+
+    .PARAMETER InputObject
+        The GitHub object to add additional properties to.
+
+    .PARAMETER TypeName
+        The type that should be assigned to the object.
+
+    .PARAMETER GistId
+        The ID of the gist that the comment is for.
+
+    .INPUTS
+        [PSCustomObject]
+
+    .OUTPUTS
+        GitHub.GistComment
+#>
+    [CmdletBinding()]
+    [OutputType({$script:GitHubGisCommentTypeName})]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline)]
+        [AllowNull()]
+        [AllowEmptyCollection()]
+        [PSCustomObject[]] $InputObject,
+
+        [ValidateNotNullOrEmpty()]
+        [string] $TypeName = $script:GitHubGistCommentTypeName
+    )
+
+    foreach ($item in $InputObject)
+    {
+        $item.PSObject.TypeNames.Insert(0, $TypeName)
+
+        if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport))
+        {
+            $hostName = $(Get-GitHubConfiguration -Name 'ApiHostName')
+            if ($item.url -match "^https?://(?:www\.|api\.|)$hostName/gists/([^/]+)/comments/(.+)$")
+            {
+                $gistId = $Matches[1]
+                $commentId = $Matches[2]
+
+                if ($commentId -ne $item.id)
+                {
+                    $message = "The gist comment url no longer follows the expected pattern.  Please contact the PowerShellForGitHubTeam: $item.url"
+                    Write-Log -Message $message -Level Warning
+                }
+            }
+
+            Add-Member -InputObject $item -Name 'GistCommentId' -Value $item.id -MemberType NoteProperty -Force
+            Add-Member -InputObject $item -Name 'GistId' -Value $gistId -MemberType NoteProperty -Force
+
+            if ($null -ne $item.user)
+            {
+                $null = Add-GitHubUserAdditionalProperties -InputObject $item.user
+            }
+        }
+
+        Write-Output $item
+    }
+}
diff --git a/GitHubGists.ps1 b/GitHubGists.ps1
new file mode 100644
index 00000000..d357bc49
--- /dev/null
+++ b/GitHubGists.ps1
@@ -0,0 +1,1884 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+@{
+    GitHubGistTypeName = 'GitHub.Gist'
+    GitHubGistCommitTypeName = 'GitHub.GistCommit'
+    GitHubGistForkTypeName = 'GitHub.GistFork'
+    GitHubGistSummaryTypeName = 'GitHub.GistSummary'
+ }.GetEnumerator() | ForEach-Object {
+     Set-Variable -Scope Script -Option ReadOnly -Name $_.Key -Value $_.Value
+ }
+
+filter Get-GitHubGist
+{
+<#
+    .SYNOPSIS
+        Retrieves gist information from GitHub.
+
+    .DESCRIPTION
+        Retrieves gist information from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to retrieve.
+
+    .PARAMETER Sha
+        The specific revision of the gist that you wish to retrieve.
+
+    .PARAMETER Forks
+        Gets the forks of the specified gist.
+
+    .PARAMETER Commits
+        Gets the commits of the specified gist.
+
+    .PARAMETER UserName
+        Gets public gists for the specified user.
+
+    .PARAMETER Path
+        Download the files that are part of the specified gist to this path.
+
+    .PARAMETER Force
+        If downloading files, this will overwrite any files with the same name in the provided path.
+
+    .PARAMETER Current
+        Gets the authenticated user's gists.
+
+    .PARAMETER Starred
+        Gets the authenticated user's starred gists.
+
+    .PARAMETER Public
+        Gets public gists sorted by most recently updated to least recently updated.
+        The results will be limited to the first 3000.
+
+    .PARAMETER Since
+        Only gists updated at or after this time are returned.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.Gist
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Get-GitHubGist -Starred
+
+        Gets all starred gists for the current authenticated user.
+
+    .EXAMPLE
+        Get-GitHubGist -Public -Since ((Get-Date).AddDays(-2))
+
+        Gets all public gists that have been updated within the past two days.
+
+    .EXAMPLE
+        Get-GitHubGist -Gist 6cad326836d38bd3a7ae
+
+        Gets octocat's "hello_world.rb" gist.
+#>
+    [CmdletBinding(
+        DefaultParameterSetName='Current',
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistTypeName})]
+    [OutputType({$script:GitHubGistCommitTypeName})]
+    [OutputType({$script:GitHubGistForkTypeName})]
+    [OutputType({$script:GitHubGistSummaryTypeName})]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            ParameterSetName='Id',
+            Position = 1)]
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            ParameterSetName='Download',
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(ParameterSetName='Id')]
+        [Parameter(ParameterSetName='Download')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Sha,
+
+        [Parameter(ParameterSetName='Id')]
+        [switch] $Forks,
+
+        [Parameter(ParameterSetName='Id')]
+        [switch] $Commits,
+
+        [Parameter(
+            Mandatory,
+            ParameterSetName='User')]
+        [ValidateNotNullOrEmpty()]
+        [string] $UserName,
+
+        [Parameter(
+            Mandatory,
+            ParameterSetName='Download',
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string] $Path,
+
+        [Parameter(ParameterSetName='Download')]
+        [switch] $Force,
+
+        [Parameter(ParameterSetName='Current')]
+        [switch] $Current,
+
+        [Parameter(ParameterSetName='Current')]
+        [switch] $Starred,
+
+        [Parameter(ParameterSetName='Public')]
+        [switch] $Public,
+
+        [Parameter(ParameterSetName='User')]
+        [Parameter(ParameterSetName='Current')]
+        [Parameter(ParameterSetName='Public')]
+        [DateTime] $Since,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    $telemetryProperties = @{}
+
+    $uriFragment = [String]::Empty
+    $description = [String]::Empty
+    $outputType = $script:GitHubGistSummaryTypeName
+
+    if ($PSCmdlet.ParameterSetName -in ('Id', 'Download'))
+    {
+        $telemetryProperties['ById'] = $true
+
+        if ($PSBoundParameters.ContainsKey('Sha'))
+        {
+            if ($Forks -or $Commits)
+            {
+                $message = 'Cannot check for forks or commits of a specific SHA.  Do not specify SHA if you want to list out forks or commits.'
+                Write-Log -Message $message -Level Error
+                throw $message
+            }
+
+            $telemetryProperties['SpecifiedSha'] = $true
+
+            $uriFragment = "gists/$Gist/$Sha"
+            $description = "Getting gist $Gist with specified Sha"
+            $outputType = $script:GitHubGistTypeName
+        }
+        elseif ($Forks)
+        {
+            $uriFragment = "gists/$Gist/forks"
+            $description = "Getting forks of gist $Gist"
+            $outputType = $script:GitHubGistForkTypeName
+        }
+        elseif ($Commits)
+        {
+            $uriFragment = "gists/$Gist/commits"
+            $description = "Getting commits of gist $Gist"
+            $outputType = $script:GitHubGistCommitTypeName
+        }
+        else
+        {
+            $uriFragment = "gists/$Gist"
+            $description = "Getting gist $Gist"
+            $outputType = $script:GitHubGistTypeName
+        }
+    }
+    elseif ($PSCmdlet.ParameterSetName -eq 'User')
+    {
+        $telemetryProperties['ByUserName'] = $true
+
+        $uriFragment = "users/$UserName/gists"
+        $description = "Getting public gists for $UserName"
+        $outputType = $script:GitHubGistSummaryTypeName
+    }
+    elseif ($PSCmdlet.ParameterSetName -eq 'Current')
+    {
+        $telemetryProperties['CurrentUser'] = $true
+        $outputType = $script:GitHubGistSummaryTypeName
+
+        if ((Test-GitHubAuthenticationConfigured) -or (-not [String]::IsNullOrEmpty($AccessToken)))
+        {
+            if ($Starred)
+            {
+                $uriFragment = 'gists/starred'
+                $description = 'Getting starred gists for current authenticated user'
+            }
+            else
+            {
+                $uriFragment = 'gists'
+                $description = 'Getting gists for current authenticated user'
+            }
+        }
+        else
+        {
+            if ($Starred)
+            {
+                $message = 'Starred can only be specified for authenticated users.  Either call Set-GitHubAuthentication first, or provide a value for the AccessToken parameter.'
+                Write-Log -Message $message -Level Error
+                throw $message
+            }
+
+            $message = 'Specified -Current, but not currently authenticated.  Either call Set-GitHubAuthentication first, or provide a value for the AccessToken parameter.'
+            Write-Log -Message $message -Level Error
+            throw $message
+        }
+    }
+    elseif ($PSCmdlet.ParameterSetName -eq 'Public')
+    {
+        $telemetryProperties['Public'] = $true
+        $outputType = $script:GitHubGistSummaryTypeName
+
+        $uriFragment = "gists/public"
+        $description = 'Getting public gists'
+    }
+
+    $getParams = @()
+    $sinceFormattedTime = [String]::Empty
+    if ($null -ne $Since)
+    {
+        $sinceFormattedTime = $Since.ToUniversalTime().ToString('o')
+        $getParams += "since=$sinceFormattedTime"
+    }
+
+    $params = @{
+        'UriFragment' = $uriFragment + '?' +  ($getParams -join '&')
+        'Description' =  $description
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    $result = (Invoke-GHRestMethodMultipleResult @params |
+        Add-GitHubGistAdditionalProperties -TypeName $outputType)
+
+    if ($PSCmdlet.ParameterSetName -eq 'Download')
+    {
+        Save-GitHubGist -GistObject $result -Path $Path -Force:$Force
+    }
+    else
+    {
+        if ($result.truncated -eq $true)
+        {
+            $message = @(
+                'Response has been truncated.  The API will only return the first 3000 gist results',
+                'the first 300 files within the gist, and the first 1 Mb of an individual',
+                'file.  If the file has been truncated, you can call',
+                '(Invoke-WebRequest -UseBasicParsing -Method Get -Uri <raw_url>).Content)',
+                'where <raw_url> is the value of raw_url for the file in question.  Be aware that',
+                'for files larger than 10 Mb, you''ll need to clone the gist via the URL provided',
+                'by git_pull_url.')
+
+            Write-Log -Message ($message -join ' ') -Level Warning
+        }
+
+        return $result
+    }
+}
+
+function Save-GitHubGist
+{
+<#
+    .SYNOPSIS
+        Downloads the contents of a gist to the specified file path.
+
+    .DESCRIPTION
+        Downloads the contents of a gist to the specified file path.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER GistObject
+        The Gist PSCustomObject
+
+    .PARAMETER Path
+        Download the files that are part of the specified gist to this path.
+
+    .PARAMETER Force
+        If downloading files, this will overwrite any files with the same name in the provided path.
+
+    .NOTES
+        Internal-only helper
+#>
+    [CmdletBinding(PositionalBinding = $false)]
+    param(
+        [Parameter(Mandatory)]
+        [PSCustomObject] $GistObject,
+
+        [Parameter(Mandatory)]
+        [ValidateNotNullOrEmpty()]
+        [string] $Path,
+
+        [switch] $Force
+    )
+
+    # First, check to see if the response is missing files.
+    if ($GistObject.truncated)
+    {
+        $message = @(
+            'Gist response has been truncated.  The API will only return information on',
+            'the first 300 files within a gist. To download this entire gist,',
+            'you''ll need to clone it via the URL provided by git_pull_url',
+            "[$($GistObject.git_pull_url)].")
+
+        Write-Log -Message ($message -join ' ') -Level Error
+        throw $message
+    }
+
+    # Then check to see if there are files we won't be able to download
+    $files = $GistObject.files | Get-Member -Type NoteProperty | Select-Object -ExpandProperty Name
+    foreach ($fileName in $files)
+    {
+        if ($GistObject.files.$fileName.truncated -and
+            ($GistObject.files.$fileName.size -gt 10mb))
+        {
+            $message = @(
+                "At least one file ($fileName) in this gist is larger than 10mb.",
+                'In order to download this gist, you''ll need to clone it via the URL',
+                "provided by git_pull_url [$($GistObject.git_pull_url)].")
+
+            Write-Log -Message ($message -join ' ') -Level Error
+            throw $message
+        }
+    }
+
+    # Finally, we're ready to directly save the non-truncated files,
+    # and download the ones that are between 1 - 10mb.
+    $originalSecurityProtocol = [Net.ServicePointManager]::SecurityProtocol
+    [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12
+    try
+    {
+        $headers = @{}
+        $AccessToken = Get-AccessToken -AccessToken $AccessToken
+        if (-not [String]::IsNullOrEmpty($AccessToken))
+        {
+            $headers['Authorization'] = "token $AccessToken"
+        }
+
+        $Path = Resolve-UnverifiedPath -Path $Path
+        $null = New-Item -Path $Path -ItemType Directory -Force
+        foreach ($fileName in $files)
+        {
+            $filePath = Join-Path -Path $Path -ChildPath $fileName
+            if ((Test-Path -Path $filePath -PathType Leaf) -and (-not $Force))
+            {
+                $message = "File already exists at path [$filePath].  Choose a different path or specify -Force"
+                Write-Log -Message $message -Level Error
+                throw $message
+            }
+
+            if ($GistObject.files.$fileName.truncated)
+            {
+                # Disable Progress Bar in function scope during Invoke-WebRequest
+                $ProgressPreference = 'SilentlyContinue'
+
+                $webRequestParams = @{
+                    UseBasicParsing = $true
+                    Method = 'Get'
+                    Headers = $headers
+                    Uri = $GistObject.files.$fileName.raw_url
+                    OutFile = $filePath
+                }
+
+                Invoke-WebRequest @webRequestParams
+            }
+            else
+            {
+                $stream = New-Object -TypeName System.IO.StreamWriter -ArgumentList ($filePath)
+                try
+                {
+                    $stream.Write($GistObject.files.$fileName.content)
+                }
+                finally
+                {
+                    $stream.Close()
+                }
+            }
+        }
+    }
+    finally
+    {
+        [Net.ServicePointManager]::SecurityProtocol = $originalSecurityProtocol
+    }
+}
+
+filter Remove-GitHubGist
+{
+<#
+    .SYNOPSIS
+        Removes/deletes a gist from GitHub.
+
+    .DESCRIPTION
+        Removes/deletes a gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to retrieve.
+
+    .PARAMETER Force
+        If this switch is specified, you will not be prompted for confirmation of command execution.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Remove-GitHubGist -Gist 6cad326836d38bd3a7ae
+
+        Removes octocat's "hello_world.rb" gist (assuming you have permission).
+
+    .EXAMPLE
+        Remove-GitHubGist -Gist 6cad326836d38bd3a7ae -Confirm:$false
+
+        Removes octocat's "hello_world.rb" gist (assuming you have permission).
+        Will not prompt for confirmation, as -Confirm:$false was specified.
+
+    .EXAMPLE
+        Remove-GitHubGist -Gist 6cad326836d38bd3a7ae -Force
+
+        Removes octocat's "hello_world.rb" gist (assuming you have permission).
+        Will not prompt for confirmation, as -Force was specified.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false,
+        ConfirmImpact = 'High')]
+    [Alias('Delete-GitHubGist')]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [switch] $Force,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    if ($Force -and (-not $Confirm))
+    {
+        $ConfirmPreference = 'None'
+    }
+
+    if (-not $PSCmdlet.ShouldProcess($Gist, "Delete gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist"
+        'Method' = 'Delete'
+        'Description' =  "Removing gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return Invoke-GHRestMethod @params
+}
+
+filter Copy-GitHubGist
+{
+<#
+    .SYNOPSIS
+        Forks a gist from GitHub.
+
+    .DESCRIPTION
+        Forks a gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to fork.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Copy-GitHubGist -Gist 6cad326836d38bd3a7ae
+
+        Forks octocat's "hello_world.rb" gist.
+
+    .EXAMPLE
+        Fork-GitHubGist -Gist 6cad326836d38bd3a7ae
+
+        Forks octocat's "hello_world.rb" gist.  This is using the alias for the command.
+        The result is the same whether you use Copy-GitHubGist or Fork-GitHubGist.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistSummaryTypeName})]
+    [Alias('Fork-GitHubGist')]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    if (-not $PSCmdlet.ShouldProcess($Gist, "Forking gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/forks"
+        'Method' = 'Post'
+        'Description' =  "Forking gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return (Invoke-GHRestMethod @params |
+        Add-GitHubGistAdditionalProperties -TypeName $script:GitHubGistSummaryTypeName)
+}
+
+filter Set-GitHubGistStar
+{
+<#
+    .SYNOPSIS
+        Changes the starred state of a gist on GitHub for the current authenticated user.
+
+    .DESCRIPTION
+        Changes the starred state of a gist on GitHub for the current authenticated user.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific Gist that you wish to change the starred state for.
+
+    .PARAMETER Star
+        Include this switch to star the gist.  Exclude the switch (or use -Star:$false) to
+        remove the star.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Set-GitHubGistStar -Gist 6cad326836d38bd3a7ae -Star
+
+        Stars octocat's "hello_world.rb" gist.
+
+    .EXAMPLE
+        Set-GitHubGistStar -Gist 6cad326836d38bd3a7ae
+
+        Unstars octocat's "hello_world.rb" gist.
+
+    .EXAMPLE
+        Get-GitHubGist -Gist 6cad326836d38bd3a7ae | Set-GitHubGistStar -Star:$false
+
+        Unstars octocat's "hello_world.rb" gist.
+
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [switch] $Star,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+    Set-TelemetryEvent -EventName $MyInvocation.MyCommand.Name
+
+    $PSBoundParameters.Remove('Star')
+    if ($Star)
+    {
+        return Add-GitHubGistStar @PSBoundParameters
+    }
+    else
+    {
+        return Remove-GitHubGistStar @PSBoundParameters
+    }
+}
+
+filter Add-GitHubGistStar
+{
+<#
+    .SYNOPSIS
+        Star a gist from GitHub.
+
+    .DESCRIPTION
+        Star a gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific Gist that you wish to star.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Add-GitHubGistStar -Gist 6cad326836d38bd3a7ae
+
+        Stars octocat's "hello_world.rb" gist.
+
+    .EXAMPLE
+        Star-GitHubGist -Gist 6cad326836d38bd3a7ae
+
+        Stars octocat's "hello_world.rb" gist.  This is using the alias for the command.
+        The result is the same whether you use Add-GitHubGistStar or Star-GitHubGist.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [Alias('Star-GitHubGist')]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    if (-not $PSCmdlet.ShouldProcess($Gist, "Starring gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/star"
+        'Method' = 'Put'
+        'Description' =  "Starring gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return Invoke-GHRestMethod @params
+}
+
+filter Remove-GitHubGistStar
+{
+<#
+    .SYNOPSIS
+        Unstar a gist from GitHub.
+
+    .DESCRIPTION
+        Unstar a gist from GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to unstar.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .EXAMPLE
+        Remove-GitHubGistStar -Gist 6cad326836d38bd3a7ae
+
+        Unstars octocat's "hello_world.rb" gist.
+
+    .EXAMPLE
+        Unstar-GitHubGist -Gist 6cad326836d38bd3a7ae
+
+        Unstars octocat's "hello_world.rb" gist.  This is using the alias for the command.
+        The result is the same whether you use Remove-GitHubGistStar or Unstar-GitHubGist.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [Alias('Unstar-GitHubGist')]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    if (-not $PSCmdlet.ShouldProcess($Gist, "Unstarring gist"))
+    {
+        return
+    }
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/star"
+        'Method' = 'Delete'
+        'Description' =  "Unstarring gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return Invoke-GHRestMethod @params
+}
+
+filter Test-GitHubGistStar
+{
+<#
+    .SYNOPSIS
+        Checks if a gist from GitHub is starred.
+
+    .DESCRIPTION
+        Checks if a gist from GitHub is starred.
+        Will return $false if it isn't starred, as well as if it couldn't be checked
+        (due to permissions or non-existence).
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID of the specific gist that you wish to check.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        Boolean indicating if the gist was both found and determined to be starred.
+
+    .EXAMPLE
+        Test-GitHubGistStar -Gist 6cad326836d38bd3a7ae
+
+        Returns $true if the gist is starred, or $false if isn't starred or couldn't be checked
+        (due to permissions or non-existence).
+#>
+    [CmdletBinding(PositionalBinding = $false)]
+    [OutputType([bool])]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    $telemetryProperties = @{}
+    $params = @{
+        'UriFragment' = "gists/$Gist/star"
+        'Method' = 'Get'
+        'Description' =  "Checking if gist $Gist is starred"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'ExtendedResult' = $true
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    try
+    {
+        $response = Invoke-GHRestMethod @params
+        return $response.StatusCode -eq 204
+    }
+    catch
+    {
+        return $false
+    }
+}
+
+filter New-GitHubGist
+{
+<#
+    .SYNOPSIS
+        Creates a new gist on GitHub.
+
+    .DESCRIPTION
+        Creates a new gist on GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER File
+        An array of filepaths that should be part of this gist.
+        Use this when you have multiple files that should be part of a gist, or when you simply
+        want to reference an existing file on disk.
+
+    .PARAMETER FileName
+        The name of the file that Content should be stored in within the newly created gist.
+
+    .PARAMETER Content
+        The content of a single file that should be part of the gist.
+
+    .PARAMETER Description
+        A descriptive name for this gist.
+
+    .PARAMETER Public
+        When specified, the gist will be public and available for anyone to see.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        String - Filename(s) of file(s) that should be the content of the gist.
+
+    .OUTPUTS
+        GitHub.GitDetail
+
+    .EXAMPLE
+        New-GitHubGist -FileName 'sample.txt' -Content 'Body of my file.' -Description 'This is my gist!' -Public
+
+        Creates a new public gist with a single file named 'sample.txt' that has the body of "Body of my file."
+
+    .EXAMPLE
+        New-GitHubGist -File 'c:\files\foo.txt' -Description 'This is my gist!'
+
+        Creates a new private gist with a single file named 'foo.txt'.  Will populate it with the
+        content of the file at c:\files\foo.txt.
+
+    .EXAMPLE
+        New-GitHubGist -File ('c:\files\foo.txt', 'c:\other\bar.txt', 'c:\octocat.ps1') -Description 'This is my gist!'
+
+        Creates a new private gist with a three files named 'foo.txt', 'bar.txt' and 'octocat.ps1'.
+        Each will be populated with the content from the file on disk at the specified location.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        DefaultParameterSetName='FileRef',
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistTypeName})]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline,
+            ParameterSetName='FileRef',
+            Position = 1)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $File,
+
+        [Parameter(
+            Mandatory,
+            ParameterSetName='Content',
+            Position = 1)]
+        [ValidateNotNullOrEmpty()]
+        [string] $FileName,
+
+        [Parameter(
+            Mandatory,
+            ParameterSetName='Content',
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string] $Content,
+
+        [string] $Description,
+
+        [switch] $Public,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    begin
+    {
+        $files = @{}
+    }
+
+    process
+    {
+        foreach ($path in $File)
+        {
+            $path = Resolve-UnverifiedPath -Path $path
+            if (-not (Test-Path -Path $path -PathType Leaf))
+            {
+                $message = "Specified file [$path] could not be found or was inaccessible."
+                Write-Log -Message $message -Level Error
+                throw $message
+            }
+
+            $content = [System.IO.File]::ReadAllText($path)
+            $fileName = (Get-Item -Path $path).Name
+
+            if ($files.ContainsKey($fileName))
+            {
+                $message = "You have specified more than one file with the same name [$fileName].  gists don't have a concept of directory structures, so please ensure each file has a unique name."
+                Write-Log -Message $message -Level Error
+                throw $message
+            }
+
+            $files[$fileName] = @{ 'content' = $Content }
+        }
+    }
+
+    end
+    {
+        Write-InvocationLog -Invocation $MyInvocation
+
+        $telemetryProperties = @{}
+
+        if ($PSCmdlet.ParameterSetName -eq 'Content')
+        {
+            $files[$FileName] = @{ 'content' = $Content }
+        }
+
+        if (($files.Keys.StartsWith('gistfile') | Where-Object { $_ -eq $true }).Count -gt 0)
+        {
+            $message = "Don't name your files starting with 'gistfile'. This is the format of the automatic naming scheme that Gist uses internally."
+            Write-Log -Message $message -Level Error
+            throw $message
+        }
+
+        $hashBody = @{
+            'description' = $Description
+            'public' = $Public.ToBool()
+            'files' = $files
+        }
+
+        if (-not $PSCmdlet.ShouldProcess('Create new gist'))
+        {
+            return
+        }
+
+        $params = @{
+            'UriFragment' = "gists"
+            'Body' = (ConvertTo-Json -InputObject $hashBody)
+            'Method' = 'Post'
+            'Description' =  "Creating a new gist"
+            'AccessToken' = $AccessToken
+            'TelemetryEventName' = $MyInvocation.MyCommand.Name
+            'TelemetryProperties' = $telemetryProperties
+            'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+        }
+
+        return (Invoke-GHRestMethod @params |
+            Add-GitHubGistAdditionalProperties -TypeName $script:GitHubGistTypeName)
+    }
+}
+
+filter Set-GitHubGist
+{
+<#
+    .SYNOPSIS
+        Updates a gist on GitHub.
+
+    .DESCRIPTION
+        Updates a gist on GitHub.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID for the gist to update.
+
+    .PARAMETER Update
+        A hashtable of files to update in the gist.
+        The key should be the name of the file in the gist as it exists right now.
+        The value should be another hashtable with the following optional key/value pairs:
+            fileName - Specify a new name here if you want to rename the file.
+            filePath - Specify a path to a file on disk if you wish to update the contents of the
+                       file in the gist with the contents of the specified file.
+                       Should not be specified if you use 'content' (below)
+            content  - Directly specify the raw content that the file in the gist should be updated with.
+                       Should not be used if you use 'filePath' (above).
+
+    .PARAMETER Delete
+        A list of filenames that should be removed from this gist.
+
+    .PARAMETER Description
+        New description for this gist.
+
+    .PARAMETER Force
+        If this switch is specified, you will not be prompted for confirmation of command execution.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.GistDetail
+
+    .EXAMPLE
+        Set-GitHubGist -Gist 6cad326836d38bd3a7ae -Description 'This is my newer description'
+
+        Updates the description for the specified gist.
+
+    .EXAMPLE
+        Set-GitHubGist -Gist 6cad326836d38bd3a7ae -Delete 'hello_world.rb' -Force
+
+        Deletes the 'hello_world.rb' file from the specified gist without prompting for confirmation.
+
+    .EXAMPLE
+        Set-GitHubGist -Gist 6cad326836d38bd3a7ae -Delete 'hello_world.rb' -Description 'This is my newer description'
+
+        Deletes the 'hello_world.rb' file from the specified gist and updates the description.
+
+    .EXAMPLE
+        Set-GitHubGist -Gist 6cad326836d38bd3a7ae -Update @{'hello_world.rb' = @{ 'fileName' = 'hello_universe.rb' }}
+
+        Renames the 'hello_world.rb' file in the specified gist to be 'hello_universe.rb'.
+
+    .EXAMPLE
+        Set-GitHubGist -Gist 6cad326836d38bd3a7ae -Update @{'hello_world.rb' = @{ 'fileName' = 'hello_universe.rb' }}
+
+        Renames the 'hello_world.rb' file in the specified gist to be 'hello_universe.rb'.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        DefaultParameterSetName='Content',
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistTypeName})]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [hashtable] $Update,
+
+        [string[]] $Delete,
+
+        [string] $Description,
+
+        [switch] $Force,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+
+    $telemetryProperties = @{}
+
+    $files = @{}
+
+    $shouldProcessMessage = 'Update gist'
+
+    # Mark the files that should be deleted.
+    if ($Delete.Count -gt 0)
+    {
+        $ConfirmPreference = 'Low'
+        $shouldProcessMessage = 'Update gist (and remove files)'
+
+        foreach ($toDelete in $Delete)
+        {
+            $files[$toDelete] = $null
+        }
+    }
+
+    # Then figure out which ones need content updates and/or file renames
+    if ($null -ne $Update)
+    {
+        foreach ($toUpdate in $Update.GetEnumerator())
+        {
+            $currentFileName = $toUpdate.Key
+
+            $providedContent = $toUpdate.Value.Content
+            $providedFileName = $toUpdate.Value.FileName
+            $providedFilePath = $toUpdate.Value.FilePath
+
+            if (-not [String]::IsNullOrWhiteSpace($providedContent))
+            {
+                $files[$currentFileName] = @{ 'content' = $providedContent }
+            }
+
+            if (-not [String]::IsNullOrWhiteSpace($providedFilePath))
+            {
+                if (-not [String]::IsNullOrWhiteSpace($providedContent))
+                {
+                    $message = "When updating a file [$currentFileName], you cannot provide both a path to a file [$providedFilePath] and the raw content."
+                    Write-Log -Message $message -Level Error
+                    throw $message
+                }
+
+                $providedFilePath = Resolve-Path -Path $providedFilePath
+                if (-not (Test-Path -Path $providedFilePath -PathType Leaf))
+                {
+                    $message = "Specified file [$providedFilePath] could not be found or was inaccessible."
+                    Write-Log -Message $message -Level Error
+                    throw $message
+                }
+
+                $newContent = [System.IO.File]::ReadAllText($providedFilePath)
+                $files[$currentFileName] = @{ 'content' = $newContent }
+            }
+
+            # The user has chosen to rename the file.
+            if (-not [String]::IsNullOrWhiteSpace($providedFileName))
+            {
+                $files[$currentFileName] = @{ 'filename' = $providedFileName }
+            }
+        }
+    }
+
+    $hashBody = @{}
+    if (-not [String]::IsNullOrWhiteSpace($Description)) { $hashBody['description'] = $Description }
+    if ($files.Keys.count -gt 0) { $hashBody['files'] = $files }
+
+    if ($Force -and (-not $Confirm))
+    {
+        $ConfirmPreference = 'None'
+    }
+
+    if (-not $PSCmdlet.ShouldProcess($Gist, $shouldProcessMessage))
+    {
+        return
+    }
+
+    $ConfirmPreference = 'None'
+    $params = @{
+        'UriFragment' = "gists/$Gist"
+        'Body' = (ConvertTo-Json -InputObject $hashBody)
+        'Method' = 'Patch'
+        'Description' =  "Updating gist $Gist"
+        'AccessToken' = $AccessToken
+        'TelemetryEventName' = $MyInvocation.MyCommand.Name
+        'TelemetryProperties' = $telemetryProperties
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    try
+    {
+        return (Invoke-GHRestMethod @params |
+            Add-GitHubGistAdditionalProperties -TypeName $script:GitHubGistTypeName)
+    }
+    catch
+    {
+        if ($_.Exception.Message -like '*(422)*')
+        {
+            $message = 'This error can happen if you try to delete a file that doesn''t exist.  Be aware that casing matters.  ''A.txt'' is not the same as ''a.txt''.'
+            Write-Log -Message $message -Level Warning
+        }
+
+        throw
+    }
+}
+
+function Set-GitHubGistFile
+{
+<#
+    .SYNOPSIS
+        Updates content of file(s) in an existing gist on GitHub,
+        or adds them if they aren't already part of the gist.
+
+    .DESCRIPTION
+        Updates content of file(s) in an existing gist on GitHub,
+        or adds them if they aren't already part of the gist.
+
+        This is a helper function built on top of Set-GitHubGist.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID for the gist to update.
+
+    .PARAMETER File
+        An array of filepaths that should be part of this gist.
+        Use this when you have multiple files that should be part of a gist, or when you simply
+        want to reference an existing file on disk.
+
+    .PARAMETER FileName
+        The name of the file that Content should be stored in within the newly created gist.
+
+    .PARAMETER Content
+        The content of a single file that should be part of the gist.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.Gist
+
+    .EXAMPLE
+        Set-GitHubGistFile -Gist 1234567 -Content 'Body of my file.' -FileName 'sample.txt'
+
+        Adds a file named 'sample.txt' that has the body of "Body of my file." to the existing
+        specified gist, or updates the contents of 'sample.txt' in the gist if is already there.
+
+    .EXAMPLE
+        Set-GitHubGistFile -Gist 1234567 -File 'c:\files\foo.txt'
+
+        Adds the file 'foo.txt' to the existing specified gist, or updates its content if it
+        is already there.
+
+    .EXAMPLE
+        Set-GitHubGistFile -Gist 1234567 -File ('c:\files\foo.txt', 'c:\other\bar.txt', 'c:\octocat.ps1')
+
+        Adds all three files to the existing specified gist, or updates the contents of the files
+        in the gist if they are already there.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        DefaultParameterSetName='Content',
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistTypeName})]
+    [Alias('Add-GitHubGistFile')]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="This is a helper method for Set-GitHubGist which will handle ShouldProcess.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline,
+            ParameterSetName='FileRef',
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $File,
+
+        [Parameter(
+            Mandatory,
+            ParameterSetName='Content',
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string] $FileName,
+
+        [Parameter(
+            Mandatory,
+            ParameterSetName='Content',
+            Position = 3)]
+        [ValidateNotNullOrEmpty()]
+        [string] $Content,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    begin
+    {
+        $files = @{}
+    }
+
+    process
+    {
+        foreach ($path in $File)
+        {
+            $path = Resolve-UnverifiedPath -Path $path
+            if (-not (Test-Path -Path $path -PathType Leaf))
+            {
+                $message = "Specified file [$path] could not be found or was inaccessible."
+                Write-Log -Message $message -Level Error
+                throw $message
+            }
+
+            $fileName = (Get-Item -Path $path).Name
+            $files[$fileName] = @{ 'filePath' = $path }
+        }
+    }
+
+    end
+    {
+        Write-InvocationLog -Invocation $MyInvocation
+        Set-TelemetryEvent -EventName $MyInvocation.MyCommand.Name
+
+        if ($PSCmdlet.ParameterSetName -eq 'Content')
+        {
+            $files[$FileName] = @{ 'content' = $Content }
+        }
+
+        $params = @{
+            'Gist' = $Gist
+            'Update' = $files
+            'AccessToken' = $AccessToken
+            'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+        }
+
+        return (Set-GitHubGist @params)
+    }
+}
+
+function Remove-GitHubGistFile
+{
+<#
+    .SYNOPSIS
+        Removes one or more files from an existing gist on GitHub.
+
+    .DESCRIPTION
+        Removes one or more files from an existing gist on GitHub.
+
+        This is a helper function built on top of Set-GitHubGist.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID for the gist to update.
+
+    .PARAMETER FileName
+        An array of filenames (no paths, just names) to remove from the gist.
+
+    .PARAMETER Force
+        If this switch is specified, you will not be prompted for confirmation of command execution.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.Gist
+
+    .EXAMPLE
+        Remove-GitHubGistFile -Gist 1234567 -FileName ('foo.txt')
+
+        Removes the file 'foo.txt' from the specified gist.
+
+    .EXAMPLE
+        Remove-GitHubGistFile -Gist 1234567 -FileName ('foo.txt') -Force
+
+        Removes the file 'foo.txt' from the specified gist without prompting for confirmation.
+
+    .EXAMPLE
+        @('foo.txt', 'bar.txt') | Remove-GitHubGistFile -Gist 1234567
+
+        Removes the files 'foo.txt' and 'bar.txt' from the specified gist.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistTypeName})]
+    [Alias('Delete-GitHubGistFile')]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="This is a helper method for Set-GitHubGist which will handle ShouldProcess.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline,
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $FileName,
+
+        [switch] $Force,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    begin
+    {
+        $files = @()
+    }
+
+    process
+    {
+        foreach ($name in $FileName)
+        {
+            $files += $name
+        }
+    }
+
+    end
+    {
+        Write-InvocationLog -Invocation $MyInvocation
+        Set-TelemetryEvent -EventName $MyInvocation.MyCommand.Name
+
+        $params = @{
+            'Gist' = $Gist
+            'Delete' = $files
+            'Force' = $Force
+            'Confirm' = ($Confirm -eq $true)
+            'AccessToken' = $AccessToken
+            'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+        }
+
+        return (Set-GitHubGist @params)
+    }
+}
+
+filter Rename-GitHubGistFile
+{
+<#
+    .SYNOPSIS
+        Renames a file in a gist on GitHub.
+
+    .DESCRIPTION
+        Renames a file in a gist on GitHub.
+
+        This is a helper function built on top of Set-GitHubGist.
+
+        The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub
+
+    .PARAMETER Gist
+        The ID for the gist to update.
+
+    .PARAMETER FileName
+        The current file in the gist to be renamed.
+
+    .PARAMETER NewName
+        The new name of the file for the gist.
+
+    .PARAMETER AccessToken
+        If provided, this will be used as the AccessToken for authentication with the
+        REST Api.  Otherwise, will attempt to use the configured value or will run unauthenticated.
+
+    .PARAMETER NoStatus
+        If this switch is specified, long-running commands will run on the main thread
+        with no commandline status update.  When not specified, those commands run in
+        the background, enabling the command prompt to provide status information.
+        If not supplied here, the DefaultNoStatus configuration property value will be used.
+
+    .INPUTS
+        GitHub.Gist
+        GitHub.GistComment
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+
+    .OUTPUTS
+        GitHub.Gist
+
+    .EXAMPLE
+        Rename-GitHubGistFile -Gist 1234567 -FileName 'foo.txt' -NewName 'bar.txt'
+
+        Renames the file 'foo.txt' to 'bar.txt' in the specified gist.
+#>
+    [CmdletBinding(
+        SupportsShouldProcess,
+        PositionalBinding = $false)]
+    [OutputType({$script:GitHubGistTypeName})]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="This is a helper method for Set-GitHubGist which will handle ShouldProcess.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipelineByPropertyName,
+            Position = 1)]
+        [Alias('GistId')]
+        [ValidateNotNullOrEmpty()]
+        [string] $Gist,
+
+        [Parameter(
+            Mandatory,
+            Position = 2)]
+        [ValidateNotNullOrEmpty()]
+        [string] $FileName,
+
+        [Parameter(
+            Mandatory,
+            Position = 3)]
+        [ValidateNotNullOrEmpty()]
+        [string] $NewName,
+
+        [string] $AccessToken,
+
+        [switch] $NoStatus
+    )
+
+    Write-InvocationLog -Invocation $MyInvocation
+    Set-TelemetryEvent -EventName $MyInvocation.MyCommand.Name
+
+    $params = @{
+        'Gist' = $Gist
+        'Update' = @{$FileName = @{ 'fileName' = $NewName }}
+        'AccessToken' = $AccessToken
+        'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -BoundParameters $PSBoundParameters -Name NoStatus -ConfigValueName DefaultNoStatus)
+    }
+
+    return (Set-GitHubGist @params)
+}
+
+filter Add-GitHubGistAdditionalProperties
+{
+<#
+    .SYNOPSIS
+        Adds type name and additional properties to ease pipelining to GitHub Gist objects.
+
+    .PARAMETER InputObject
+        The GitHub object to add additional properties to.
+
+    .PARAMETER TypeName
+        The type that should be assigned to the object.
+
+    .INPUTS
+        [PSCustomObject]
+
+    .OUTPUTS
+        GitHub.Gist
+        GitHub.GistCommit
+        GitHub.GistFork
+        GitHub.GistSummary
+#>
+    [CmdletBinding()]
+    [OutputType({$script:GitHubGistTypeName})]
+    [OutputType({$script:GitHubGistFormTypeName})]
+    [OutputType({$script:GitHubGistSummaryTypeName})]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline)]
+        [AllowNull()]
+        [AllowEmptyCollection()]
+        [PSCustomObject[]] $InputObject,
+
+        [ValidateNotNullOrEmpty()]
+        [string] $TypeName = $script:GitHubGistSummaryTypeName
+    )
+
+    if ($TypeName -eq $script:GitHubGistCommitTypeName)
+    {
+        return Add-GitHubGistCommitAdditionalProperties -InputObject $InputObject
+    }
+    elseif ($TypeName -eq $script:GitHubGistForkTypeName)
+    {
+        return Add-GitHubGistForkAdditionalProperties -InputObject $InputObject
+    }
+
+    foreach ($item in $InputObject)
+    {
+        $item.PSObject.TypeNames.Insert(0, $TypeName)
+
+        if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport))
+        {
+            Add-Member -InputObject $item -Name 'GistId' -Value $item.id -MemberType NoteProperty -Force
+
+            @('user', 'owner') |
+                ForEach-Object {
+                    if ($null -ne $item.$_)
+                    {
+                        $null = Add-GitHubUserAdditionalProperties -InputObject $item.$_
+                    }
+                }
+
+            if ($null -ne $item.forks)
+            {
+                $item.forks = Add-GitHubGistForkAdditionalProperties -InputObject $item.forks
+            }
+
+            if ($null -ne $item.history)
+            {
+                $item.history = Add-GitHubGistCommitAdditionalProperties -InputObject $item.history
+            }
+        }
+
+        Write-Output $item
+    }
+}
+
+filter Add-GitHubGistCommitAdditionalProperties
+{
+<#
+    .SYNOPSIS
+        Adds type name and additional properties to ease pipelining to GitHub GistCommit objects.
+
+    .PARAMETER InputObject
+        The GitHub object to add additional properties to.
+
+    .PARAMETER TypeName
+        The type that should be assigned to the object.
+
+    .INPUTS
+        [PSCustomObject]
+
+    .OUTPUTS
+        GitHub.GistCommit
+#>
+    [CmdletBinding()]
+    [OutputType({$script:GitHubGistCommitTypeName})]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline)]
+        [AllowNull()]
+        [AllowEmptyCollection()]
+        [PSCustomObject[]] $InputObject,
+
+        [ValidateNotNullOrEmpty()]
+        [string] $TypeName = $script:GitHubGistCommitTypeName
+    )
+
+    foreach ($item in $InputObject)
+    {
+        $item.PSObject.TypeNames.Insert(0, $TypeName)
+
+        if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport))
+        {
+            $hostName = $(Get-GitHubConfiguration -Name 'ApiHostName')
+            if ($item.url -match "^https?://(?:www\.|api\.|)$hostName/gists/([^/]+)/(.+)$")
+            {
+                $id = $Matches[1]
+                $sha = $Matches[2]
+
+                if ($sha -ne $item.version)
+                {
+                    $message = "The gist commit url no longer follows the expected pattern.  Please contact the PowerShellForGitHubTeam: $item.uri"
+                    Write-Log -Message $message -Level Warning
+                }
+            }
+
+            Add-Member -InputObject $item -Name 'GistId' -Value $id -MemberType NoteProperty -Force
+            Add-Member -InputObject $item -Name 'Sha' -Value $item.version -MemberType NoteProperty -Force
+
+            $null = Add-GitHubUserAdditionalProperties -InputObject $item.user
+        }
+
+        Write-Output $item
+    }
+}
+
+filter Add-GitHubGistForkAdditionalProperties
+{
+<#
+    .SYNOPSIS
+        Adds type name and additional properties to ease pipelining to GitHub Gist Fork objects.
+
+    .PARAMETER InputObject
+        The GitHub object to add additional properties to.
+
+    .PARAMETER TypeName
+        The type that should be assigned to the object.
+
+    .INPUTS
+        [PSCustomObject]
+
+    .OUTPUTS
+        GitHub.GistFork
+#>
+    [CmdletBinding()]
+    [OutputType({$script:GitHubGistForkTypeName})]
+    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Justification="Internal helper that is definitely adding more than one property.")]
+    param(
+        [Parameter(
+            Mandatory,
+            ValueFromPipeline)]
+        [AllowNull()]
+        [AllowEmptyCollection()]
+        [PSCustomObject[]] $InputObject,
+
+        [ValidateNotNullOrEmpty()]
+        [string] $TypeName = $script:GitHubGistForkTypeName
+    )
+
+    foreach ($item in $InputObject)
+    {
+        $item.PSObject.TypeNames.Insert(0, $TypeName)
+
+        if (-not (Get-GitHubConfiguration -Name DisablePipelineSupport))
+        {
+            Add-Member -InputObject $item -Name 'GistId' -Value $item.id -MemberType NoteProperty -Force
+
+            # See here for why we need to work with both 'user' _and_ 'owner':
+            # https://github.community/t/gist-api-v3-documentation-incorrect-for-forks/122545
+            @('user', 'owner') |
+            ForEach-Object {
+                if ($null -ne $item.$_)
+                {
+                    $null = Add-GitHubUserAdditionalProperties -InputObject $item.$_
+                }
+            }
+        }
+
+        Write-Output $item
+    }
+}
\ No newline at end of file
diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1
index 3063585b..5cbc5e48 100644
--- a/PowerShellForGitHub.psd1
+++ b/PowerShellForGitHub.psd1
@@ -15,6 +15,8 @@
 
     # Format files (.ps1xml) to be loaded when importing this module
     FormatsToProcess = @(
+        'Formatters/GitHubGistComments.Format.ps1xml',
+        'Formatters/GitHubGists.Format.ps1xml',
         'Formatters/GitHubReleases.Format.ps1xml'
         'Formatters/GitHubRepositories.Format.ps1xml'
     )
@@ -32,6 +34,8 @@
         'GitHubCore.ps1',
         'GitHubContents.ps1',
         'GitHubEvents.ps1',
+        'GitHubGistComments.ps1',
+        'GitHubGists.ps1',
         'GitHubIssueComments.ps1',
         'GitHubIssues.ps1',
         'GitHubLabels.ps1',
@@ -59,9 +63,11 @@
     FunctionsToExport = @(
         'Add-GitHubAssignee',
         'Add-GitHubIssueLabel',
+        'Add-GitHubGistStar',
         'Backup-GitHubConfiguration',
         'Clear-GitHubAuthentication',
         'ConvertFrom-GitHubMarkdown',
+        'Copy-GitHubGist',
         'Disable-GitHubRepositorySecurityFix',
         'Disable-GitHubRepositoryVulnerabilityAlert',
         'Enable-GitHubRepositorySecurityFix',
@@ -73,6 +79,8 @@
         'Get-GitHubContent',
         'Get-GitHubEmoji',
         'Get-GitHubEvent',
+        'Get-GitHubGist',
+        'Get-GitHubGistComment',
         'Get-GitHubGitIgnore',
         'Get-GitHubIssue',
         'Get-GitHubIssueComment',
@@ -115,6 +123,8 @@
         'Move-GitHubProjectCard',
         'Move-GitHubProjectColumn',
         'Move-GitHubRepositoryOwnership',
+        'New-GitHubGist',
+        'New-GitHubGistComment',
         'New-GitHubIssue',
         'New-GitHubIssueComment',
         'New-GitHubLabel',
@@ -130,6 +140,11 @@
         'New-GitHubRepositoryBranch',
         'New-GitHubRepositoryFork',
         'Remove-GitHubAssignee',
+        'Remove-GitHubComment',
+        'Remove-GitHubGist',
+        'Remove-GitHubGistComment',
+        'Remove-GitHubGistFile',
+        'Remove-GitHubGistStar',
         'Remove-GitHubIssueComment',
         'Remove-GitHubIssueLabel',
         'Remove-GitHubLabel',
@@ -142,12 +157,17 @@
         'Remove-GitHubReleaseAsset',
         'Remove-GitHubRepository',
         'Remove-GitHubRepositoryBranch'
+        'Rename-GitHubGistFile',
         'Rename-GitHubRepository',
         'Reset-GitHubConfiguration',
         'Restore-GitHubConfiguration',
         'Set-GitHubAuthentication',
         'Set-GitHubConfiguration',
         'Set-GitHubContent',
+        'Set-GitHubGist',
+        'Set-GitHubGistComment',
+        'Set-GitHubGistFile',
+        'Set-GitHubGistStar',
         'Set-GitHubIssue',
         'Set-GitHubIssueComment',
         'Set-GitHubIssueLabel',
@@ -165,15 +185,20 @@
         'Split-GitHubUri',
         'Test-GitHubAssignee',
         'Test-GitHubAuthenticationConfigured',
+        'Test-GitHubGistStar',
         'Test-GitHubOrganizationMember',
         'Test-GitHubRepositoryVulnerabilityAlert',
         'Unlock-GitHubIssue'
     )
 
     AliasesToExport = @(
+        'Add-GitHubGistFile',
         'Delete-GitHubAsset',
         'Delete-GitHubBranch',
         'Delete-GitHubComment',
+        'Delete-GitHubGist',
+        'Delete-GitHubGistComment',
+        'Delete-GitHubGistFile',
         'Delete-GitHubIssueComment',
         'Delete-GitHubLabel',
         'Delete-GitHubMilestone',
@@ -185,6 +210,7 @@
         'Delete-GitHubReleaseAsset',
         'Delete-GitHubRepository',
         'Delete-GitHubRepositoryBranch',
+        'Fork-GitHubGist',
         'Get-GitHubAsset',
         'Get-GitHubBranch',
         'Get-GitHubComment',
@@ -197,7 +223,9 @@
         'Remove-GitHubComment',
         'Set-GitHubAsset',
         'Set-GitHubComment',
+        'Star-GitHubGist',
         'Transfer-GitHubRepositoryOwnership'
+        'Unstar-GitHubGist'
         'Update-GitHubIssue',
         'Update-GitHubLabel',
         'Update-GitHubCurrentUser',
diff --git a/Tests/GitHubGistComments.tests.ps1 b/Tests/GitHubGistComments.tests.ps1
new file mode 100644
index 00000000..ab14b510
--- /dev/null
+++ b/Tests/GitHubGistComments.tests.ps1
@@ -0,0 +1,335 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+<#
+.Synopsis
+   Tests for GitHubGistCommentss.ps1 module
+#>
+
+[CmdletBinding()]
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '',
+    Justification='Suppress false positives in Pester code blocks')]
+param()
+
+# This is common test code setup logic for all Pester test files
+$moduleRootPath = Split-Path -Path $PSScriptRoot -Parent
+. (Join-Path -Path $moduleRootPath -ChildPath 'Tests\Common.ps1')
+
+try
+{
+    Describe 'Get-GitHubGistComment' {
+        BeforeAll {
+            $body = 'Comment body'
+        }
+
+        Context 'By parameters' {
+            BeforeAll {
+                $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+                $body = 'Comment body'
+            }
+
+            AfterAll {
+                $gist | Remove-GitHubGist -Force
+            }
+
+            $comments = @(Get-GitHubGistComment -Gist $gist.id -MediaType 'Raw')
+            It 'Should have no comments so far' {
+                $comments.Count | Should -Be 0
+            }
+
+            $firstComment = New-GitHubGistComment -Gist $gist.id -Body $body
+            $comments = @(Get-GitHubGistComment -Gist $gist.id -MediaType 'Text')
+            It 'Should have one comments so far' {
+                $comments.Count | Should -Be 1
+                $comments[0].id | Should -Be $firstComment.id
+                $comments[0].body | Should -BeNullOrEmpty
+                $comments[0].body_html | Should -BeNullOrEmpty
+                $comments[0].body_text | Should -Not -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comments[0].PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comments[0].GistCommentId | Should -Be $comments[0].id
+                $comments[0].GistId | Should -Be $gist.id
+                $comments[0].user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $null = New-GitHubGistComment -Gist $gist.id -Body $body
+            $comments = @(Get-GitHubGistComment -Gist $gist.id -MediaType 'Html')
+            It 'Should have one comments so far' {
+                $comments.Count | Should -Be 2
+                foreach ($comment in $comments)
+                {
+                    $comment.body | Should -BeNullOrEmpty
+                    $comment.body_html | Should -Not -BeNullOrEmpty
+                    $comment.body_text | Should -BeNullOrEmpty
+                }
+            }
+
+            It 'Should have the expected type and additional properties' {
+                foreach ($comment in $comments)
+                {
+                    $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                    $comment.GistCommentId | Should -Be $comment.id
+                    $comment.GistId | Should -Be $gist.id
+                    $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                }
+            }
+
+            $comment = Get-GitHubGistComment -Gist $gist.id -Comment $firstComment.id -MediaType 'Html'
+            It 'Should retrieve the specific comment' {
+                $comment.id | Should -Be $firstComment.id
+                $comment.body | Should -BeNullOrEmpty
+                $comment.body_html | Should -Not -BeNullOrEmpty
+                $comment.body_text | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+
+        Context 'Gist on the pipeline' {
+            BeforeAll {
+                $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+                $body = 'Comment body'
+            }
+
+            AfterAll {
+                $gist | Remove-GitHubGist -Force
+            }
+
+            $comments = @(Get-GitHubGistComment -Gist $gist.id -MediaType 'Text')
+            It 'Should have no comments so far' {
+                $comments.Count | Should -Be 0
+            }
+
+            $firstComment = $gist | New-GitHubGistComment -Body $body
+            $comments = @($gist | Get-GitHubGistComment -MediaType 'Raw')
+            It 'Should have one comments so far' {
+                $comments.Count | Should -Be 1
+                $comments[0].id | Should -Be $firstComment.id
+                $comments[0].body | Should -Not -BeNullOrEmpty
+                $comments[0].body_html | Should -BeNullOrEmpty
+                $comments[0].body_text | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comments[0].PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comments[0].GistCommentId | Should -Be $comments[0].id
+                $comments[0].GistId | Should -Be $gist.id
+                $comments[0].user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $null = $gist | New-GitHubGistComment -Body $body
+            $comments = @($gist | Get-GitHubGistComment -MediaType 'Full')
+            It 'Should have one comments so far' {
+                $comments.Count | Should -Be 2
+                foreach ($comment in $comments)
+                {
+                    $comment.body | Should -Not -BeNullOrEmpty
+                    $comment.body_html | Should -Not -BeNullOrEmpty
+                    $comment.body_text | Should -Not -BeNullOrEmpty
+                }
+            }
+
+            It 'Should have the expected type and additional properties' {
+                foreach ($comment in $comments)
+                {
+                    $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                    $comment.GistCommentId | Should -Be $comment.id
+                    $comment.GistId | Should -Be $gist.id
+                    $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                }
+            }
+
+            $comment = Get-GitHubGistComment -Gist $gist.id -Comment $firstComment.id -MediaType 'Html'
+            It 'Should retrieve the specific comment' {
+                $comment.id | Should -Be $firstComment.id
+                $comment.body | Should -BeNullOrEmpty
+                $comment.body_html | Should -Not -BeNullOrEmpty
+                $comment.body_text | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $comment = $firstComment | Get-GitHubGistComment -MediaType 'Html'
+            It 'Should retrieve the specific comment with the comment on the pipeline' {
+                $comment.id | Should -Be $firstComment.id
+                $comment.body | Should -BeNullOrEmpty
+                $comment.body_html | Should -Not -BeNullOrEmpty
+                $comment.body_text | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+    }
+
+    Describe 'New-GitHubGistComment' {
+        BeforeAll {
+            $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+            $body = 'Comment body'
+        }
+
+        AfterAll {
+            $gist | Remove-GitHubGist -Force
+        }
+
+        Context 'By parameters' {
+            $comment = New-GitHubGistComment -Gist $gist.id -Body $body
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $body
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+
+        Context 'Gist on the pipeline' {
+            $comment = $gist | New-GitHubGistComment -Body $body
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $body
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+    }
+
+    Describe 'New-GitHubGistComment' {
+        BeforeAll {
+            $gist = New-GitHubGist -Filename 'sample.txt' -Content 'Sample text'
+            $body = 'Comment body'
+            $updatedBody = 'Updated comment body'
+        }
+
+        AfterAll {
+            $gist | Remove-GitHubGist -Force
+        }
+
+        Context 'By parameters' {
+            $comment = New-GitHubGistComment -Gist $gist.id -Body $body
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $body
+            }
+
+            $comment = Set-GitHubGistComment -Gist $gist.id -Comment $comment.id -Body $updatedBody
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $updatedBody
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+
+        Context 'Gist on the pipeline' {
+            $comment = $gist | New-GitHubGistComment -Body $body
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $body
+            }
+
+            $comment = $gist | Set-GitHubGistComment -Comment $comment.id -Body $updatedBody
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $updatedBody
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+
+        Context 'Gist Comment on the pipeline' {
+            $comment = $gist | New-GitHubGistComment -Body $body
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $body
+            }
+
+            $comment = $comment | Set-GitHubGistComment -Body $updatedBody
+            It 'Should have the expected result' {
+                $comment.body | Should -Be $updatedBody
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $comment.PSObject.TypeNames[0] | Should -Be 'GitHub.GistComment'
+                $comment.GistCommentId | Should -Be $comment.id
+                $comment.GistId | Should -Be $gist.id
+                $comment.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+        }
+    }
+
+    Describe 'Remove-GitHubGistComment' {
+        BeforeAll {
+            $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+            $body = 'Comment body'
+        }
+
+        AfterAll {
+            $gist | Remove-GitHubGist -Force
+        }
+
+        Context 'By parameters' {
+            $comment = New-GitHubGistComment -Gist $gist.id -Body $body
+
+            Remove-GitHubGistComment -Gist $gist.id -Comment $comment.id -Force
+            It 'Should be gone' {
+                { Get-GitHubGistComment -Gist $gist.id -Comment $comment.id } | Should -Throw
+            }
+        }
+
+        Context 'Gist on the pipeline' {
+            $comment = $gist | New-GitHubGistComment -Body $body
+
+            $gist | Remove-GitHubGistComment -Comment $comment.id -Force
+            It 'Should be gone' {
+                { $gist | Get-GitHubGistComment -Comment $comment.id } | Should -Throw
+            }
+        }
+
+        Context 'Gist Comment on the pipeline' {
+            $comment = $gist | New-GitHubGistComment -Body $body
+
+            $comment | Remove-GitHubGistComment -Force
+            It 'Should be gone' {
+                { $comment | Get-GitHubGistComment } | Should -Throw
+            }
+        }
+    }
+}
+finally
+{
+    if (Test-Path -Path $script:originalConfigFile -PathType Leaf)
+    {
+        # Restore the user's configuration to its pre-test state
+        Restore-GitHubConfiguration -Path $script:originalConfigFile
+        $script:originalConfigFile = $null
+    }
+}
diff --git a/Tests/GitHubGists.tests.ps1 b/Tests/GitHubGists.tests.ps1
new file mode 100644
index 00000000..67e06ccf
--- /dev/null
+++ b/Tests/GitHubGists.tests.ps1
@@ -0,0 +1,1193 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+<#
+.Synopsis
+   Tests for GitHubGists.ps1 module
+#>
+
+[CmdletBinding()]
+[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '',
+    Justification='Suppress false positives in Pester code blocks')]
+param()
+
+# This is common test code setup logic for all Pester test files
+$moduleRootPath = Split-Path -Path $PSScriptRoot -Parent
+. (Join-Path -Path $moduleRootPath -ChildPath 'Tests\Common.ps1')
+
+filter New-LargeFile
+{
+<#
+    .SYNOPSIS
+        Creates a large dummy file with random conntent
+
+    .DESCRIPTION
+        Creates a large dummy file with random conntent
+        Credits for the random content creation logic goes to Robert Robelo
+
+    .PARAMETER Path
+        The full path to the file to create.
+
+    .PARAMETER SizeMB
+        The size of the random file to be genrated. Default is one MB
+
+    .PARAMETER Type
+        The type of file should be created.
+
+    .PARAMETER Force
+        Will allow this to overwrite the target file if it already exists.
+
+    .EXAMPLE
+        New-LargeFile -Path C:\Temp\LF\bigfile.txt -SizeMB 10
+#>
+
+    [CmdletBinding(SupportsShouldProcess)]
+    param(
+        [Parameter(ValueFromPipeline)]
+        [String] $Path,
+
+        [ValidateRange(1, 5120)]
+        [UInt16] $SizeMB = 1,
+
+        [ValidateSet('Text', 'Binary')]
+        [string] $Type = 'Text',
+
+        [switch] $Force
+    )
+
+    $tempFile = New-TemporaryFile
+
+    if ($Type -eq 'Text')
+    {
+        $streamWriter = New-Object -TypeName IO.StreamWriter -ArgumentList ($tempFile)
+        try
+        {
+            # get a 64 element Char[]; I added the - and \n to have 64 chars
+            [char[]]$chars = 'azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789-\n'
+            1..$SizeMB | ForEach-Object {
+                # get 1MB of chars from 4 256KB strings
+                1..4 | ForEach-Object {
+                    $randomizedChars = $chars | Get-Random -Count $chars.Count
+
+                    # repeat random string 4096 times to get a 256KB string
+                    $output = (-join $randomizedChars) * 4kb
+
+                    # write 256KB string to file
+                    $streamWriter.Write($output)
+
+                    # release resources
+                    Clear-Variable -Name @('randomizedChars', 'output')
+                }
+            }
+        }
+        catch
+        {
+            Remove-File -Path $tempFile -ErrorAction SilentlyContinue
+        }
+        finally
+        {
+            $streamWriter.Close()
+            $streamWriter.Dispose()
+
+            # Force the immediate garbage collection of allocated resources
+            [GC]::Collect()
+        }
+    }
+    else
+    {
+        $content = New-Object -TypeName Byte[] -ArgumentList ($SizeMB * 1mb)
+        (New-Object -TypeName Random).NextBytes($content)
+        [IO.File]::WriteAllBytes($tempFile, $content)
+    }
+
+    try
+    {
+        if ($PSBoundParameters.ContainsKey('Path'))
+        {
+            return (Move-Item -Path $tempFile -Destination $Path -Force:$Force)
+        }
+        else
+        {
+            return (Get-Item -Path $tempFile)
+        }
+    }
+    catch
+    {
+        Remove-File -Path $tempFile -ErrorAction SilentlyContinue
+    }
+}
+
+try
+{
+    Describe 'Get-GitHubGist' {
+        Context 'Specific Gist' {
+            $id = '0831f3fbd83ac4d46451' # octocat/git-author-rewrite.sh
+            $gist = Get-GitHubGist -Gist $id
+            It 'Should be the expected gist' {
+                $gist.id | Should -Be $id
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                $gist.history[0].PSObject.TypeNames[0] | Should -Be 'GitHub.GistCommit'
+                $gist.forks[0].PSObject.TypeNames[0] | Should -Be 'GitHub.GistFork'
+            }
+
+            $gist = $gist | Get-GitHubGist
+            It 'Should be the expected gist with the gist on the pipeline' {
+                $gist.id | Should -Be $id
+            }
+        }
+
+        Context 'Commits and specific Gist with Sha' {
+            $id = '0831f3fbd83ac4d46451' # octocat/git-author-rewrite.sh
+
+            $gist = Get-GitHubGist -Gist $id
+            $commits = Get-GitHubGist -Gist $gist.id -Commits
+
+            It 'Should have multiple commits' {
+                $commits.Count | Should -BeGreaterThan 1
+            }
+
+            It 'Should have the expected type and additional properties' {
+                foreach ($commit in $commits)
+                {
+                    $commit.PSObject.TypeNames[0] | Should -Be 'GitHub.GistCommit'
+                    $commit.GistId | Should -Be $gist.id
+                    $commit.Sha | Should -Be $commit.version
+                    $commit.user.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                }
+            }
+
+            $oldestSha = $commits | Sort-Object -Property 'committed_at' | Select-Object -First 1
+
+            $firstGistCommit = Get-GitHubGist -Gist $gist.id -Sha $oldestSha.version
+            It 'Should be the expected commit' {
+                $firstGistCommit.created_at | Should -Be $oldestSha.committed_at
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $firstGistCommit.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $firstGistCommit.GistId | Should -Be $firstGistCommit.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                $gist.history[0].PSObject.TypeNames[0] | Should -Be 'GitHub.GistCommit'
+                $gist.forks[0].PSObject.TypeNames[0] | Should -Be 'GitHub.GistFork'
+            }
+
+            It 'Should fail if we specify Sha _and_ Commits' {
+                { Get-GitHubGist -Gist $gist.id -Commits -Sha $oldestSha.version } | Should -Throw
+            }
+
+            It 'Should fail if we specify Sha _and_ Forks' {
+                { Get-GitHubGist -Gist $gist.id -Forks -Sha $oldestSha.version } | Should -Throw
+            }
+
+            $firstGistCommit = $gist | Get-GitHubGist -Sha $oldestSha.version
+            It 'Should be the expected gist commit with the gist on the pipeline' {
+                $firstGistCommit.created_at | Should -Be $oldestSha.committed_at
+            }
+
+            $firstGistCommit = $firstGistCommit | Get-GitHubGist
+            It 'Should be the expected gist commit with the gist commit on the pipeline' {
+                $firstGistCommit.created_at | Should -Be $oldestSha.committed_at
+            }
+        }
+
+        Context 'Forks' {
+            $id = '0831f3fbd83ac4d46451' # octocat/git-author-rewrite.sh
+
+            $gist = Get-GitHubGist -Gist $id
+            $forks = Get-GitHubGist -Gist $gist.id -Forks
+
+            It 'Should have multiple forks' {
+                $forks.Count | Should -BeGreaterThan 1
+            }
+
+            It 'Should have the expected type and additional properties' {
+                foreach ($fork in $forks)
+                {
+                    $fork.PSObject.TypeNames[0] | Should -Be 'GitHub.GistFork'
+                    $fork.GistId | Should -Be $fork.id
+                    $fork.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                }
+            }
+
+            $forks = $gist | Get-GitHubGist -Forks
+
+            It 'Should have multiple forks when gist is on the pipeline' {
+                $forks.Count | Should -BeGreaterThan 1
+            }
+        }
+
+        Context 'All gists for a specific user' {
+            $username = 'octocat'
+            $gists = Get-GitHubGist -UserName $username
+
+            It 'Should have multiple gists' {
+                $gists.Count | Should -BeGreaterThan 1
+            }
+
+            It 'Should have the expected type and additional properties' {
+                foreach ($gist in $gists)
+                {
+                    $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.GistSummary'
+                    $gist.GistId | Should -Be $gist.id
+                    $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                }
+            }
+
+            $since = (Get-Date -Date '01/01/2016')
+            $sinceGists = Get-GitHubGist -UserName $username -Since $since
+            It 'Should have fewer results with using the since parameter' {
+                $sinceGists.Count | Should -BeGreaterThan 0
+                $sinceGists.Count | Should -BeLessThan $gists.Count
+            }
+        }
+
+        Context 'All gists for the current authenticated user' {
+            $gist = New-GitHubGist -Filename 'sample.txt' -Content 'Sample text'
+            $gists = @(Get-GitHubGist)
+            It 'Should at least one gist including the one just created' {
+                $gists.Count | Should -BeGreaterOrEqual 1
+                $gists.id | Should -Contain $gist.id
+            }
+
+            It 'Should have the expected type and additional properties' {
+                foreach ($gist in $gists)
+                {
+                    $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.GistSummary'
+                    $gist.GistId | Should -Be $gist.id
+                    $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+                }
+            }
+
+            It 'Should be removed' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'All gists for the current authenticated user, but not authenticated' {
+            # This would just be testing that an exception is thrown.
+            # There's no easy way to cover unauthenticated sessions in the UT's,
+            # so we'll just accept the lower code coverage here.
+        }
+
+        Context 'All starred gists for the current authenticated user' {
+            $id = '0831f3fbd83ac4d46451' # octocat/git-author-rewrite.sh
+            Add-GitHubGistStar -Gist $id
+
+            $gists = @(Get-GitHubGist -Starred)
+            It 'Should include the one we just starred' {
+                $gists.Count | Should -BeGreaterOrEqual 1
+                $gists.id | Should -Contain $id
+            }
+
+            Remove-GitHubGistStar -Gist $id
+        }
+
+        Context 'All starred gists for the current authenticated user, but not authenticated' {
+            # This would just be testing that an exception is thrown.
+            # There's no easy way to cover unauthenticated sessions in the UT's,
+            # so we'll just accept the lower code coverage here.
+        }
+
+        Context 'All public gists' {
+            # This would require 100 queries, taking over 2 minutes.
+            # Given the limited additional value that we'd get from this additional test relative
+            # to the time it would take to execute, we'll just accept the lower code coverage here.
+        }
+    }
+
+    Describe 'Get-GitHubGist/Download' {
+        BeforeAll {
+            # To get access to New-TemporaryDirectory
+            $moduleRootPath = Split-Path -Path $PSScriptRoot -Parent
+            . (Join-Path -Path $moduleRootPath -ChildPath 'Helpers.ps1')
+            $tempPath = New-TemporaryDirectory
+        }
+
+        AfterAll {
+            if (Get-Variable -Name tempPath -ErrorAction SilentlyContinue)
+            {
+                Remove-Item -Path $tempPath -Recurse -ErrorAction SilentlyContinue -Force
+            }
+        }
+
+        Context 'Download gist content' {
+            BeforeAll {
+                $tempFile = New-TemporaryFile
+                $fileA = "$($tempFile.FullName).ps1"
+                Move-Item -Path $tempFile -Destination $fileA
+                $fileAName = (Get-Item -Path $fileA).Name
+                $fileAContent = 'fileA content'
+                Out-File -FilePath $fileA -InputObject $fileAContent -Encoding utf8
+
+                $tempFile = New-TemporaryFile
+                $fileB = "$($tempFile.FullName).txt"
+                Move-Item -Path $tempFile -Destination $fileB
+                $fileBName = (Get-Item -Path $fileB).Name
+                $fileBContent = 'fileB content'
+                Out-File -FilePath $fileB -InputObject $fileBContent -Encoding utf8
+
+                $tempFile = New-LargeFile -SizeMB 1
+                $twoMegFile = "$($tempFile.FullName).bin"
+                Move-Item -Path $tempFile -Destination $twoMegFile
+                $twoMegFileName = (Get-Item -Path $twoMegFile).Name
+
+                $gist = @($fileA, $fileB, $twoMegFile) | New-GitHubGist
+            }
+
+            AfterAll {
+                $gist | Remove-GitHubGist -Force
+                @($fileA, $fileB, $twoMegFile) |
+                    Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            It 'Should have no files at the download path' {
+                @(Get-ChildItem -Path $tempPath).Count | Should -Be 0
+            }
+
+            Get-GitHubGist -Gist $gist.id -Path $tempPath
+            It 'Should download all of the files' {
+                @(Get-ChildItem -Path $tempPath).Count | Should -Be 3
+                [System.IO.File]::ReadAllText($fileA).Trim() |
+                    Should -Be ([System.IO.File]::ReadAllText((Join-Path -Path $tempPath -ChildPath $fileAName)).Trim())
+                [System.IO.File]::ReadAllText($fileB).Trim() |
+                    Should -Be ([System.IO.File]::ReadAllText((Join-Path -Path $tempPath -ChildPath $fileBName)).Trim())
+                (Get-FileHash -Path $twoMegFile).Hash |
+                    Should -Be (Get-FileHash -Path (Join-Path -Path $tempPath -ChildPath $twoMegFileName)).Hash
+            }
+
+            $gist | Get-GitHubGist -Path $tempPath -Force
+            It 'Should download all of the files with the gist on the pipeline and -Force' {
+                @(Get-ChildItem -Path $tempPath).Count | Should -Be 3
+                [System.IO.File]::ReadAllText($fileA).Trim() |
+                    Should -Be ([System.IO.File]::ReadAllText((Join-Path -Path $tempPath -ChildPath $fileAName)).Trim())
+                [System.IO.File]::ReadAllText($fileB).Trim() |
+                    Should -Be ([System.IO.File]::ReadAllText((Join-Path -Path $tempPath -ChildPath $fileBName)).Trim())
+                (Get-FileHash -Path $twoMegFile).Hash |
+                    Should -Be (Get-FileHash -Path (Join-Path -Path $tempPath -ChildPath $twoMegFileName)).Hash
+            }
+        }
+
+        Context 'More than 300 files' {
+            BeforeAll {
+                $files = @()
+                1..301 | ForEach-Object {
+                    $tempFile = New-TemporaryFile
+                    $file = "$($tempFile.FullName)-$_.ps1"
+                    Move-Item -Path $tempFile -Destination $file
+                    $fileContent = "file-$_ content"
+                    Out-File -FilePath $file -InputObject $fileContent -Encoding utf8
+                    $files += $file
+                }
+            }
+
+            AfterAll {
+                $files | Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            # May want to consider skipping this test.
+            # It works just fine, but takes 26 second to execute.
+            # (May not be worth it for the moderate improvement to code coverage.)
+            It 'Should throw an exception because there are too many files' {
+                $gist = $files | New-GitHubGist
+                { $gist | Get-GitHubGist -Path $tempPath -Force } | Should -Throw
+                $gist | Remove-GitHubGist -Force
+            }
+
+        }
+
+        Context 'Download gist content' {
+            BeforeAll {
+                $tempFile = New-LargeFile -SizeMB 10
+                $tenMegFile = "$($tempFile.FullName).bin"
+                Move-Item -Path $tempFile -Destination $tenMegFile
+                $tenMegFileName = (Get-Item -Path $tenMegFile).Name
+            }
+
+            AfterAll {
+                @($tenMegFile) |
+                    Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            # May want to consider skipping this test.
+            # It works just fine, but takes 26 second to execute.
+            # (May not be worth it for the moderate improvement to code coverage.)
+            It 'Should throw an exception because the file is too large to download' {
+                $gist = $tenMegFile | New-GitHubGist
+                { $gist | Get-GitHubGist -Path $tempPath -Force } | Should -Throw
+                $gist | Remove-GitHubGist -Force
+            }
+        }
+    }
+
+    Describe 'Remove-GitHubGist' {
+        Context 'With parameters' {
+            $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+            It 'Should be there' {
+                { Get-GitHubGist -Gist $gist.id } | Should -Not -Throw
+            }
+
+            It 'Should remove the gist successfully' {
+                { Remove-GitHubGist -Gist $gist.id -Force } | Should -Not -Throw
+            }
+
+            It 'Should be removed' {
+                { Get-GitHubGist -Gist $gist.id } | Should -Throw
+            }
+        }
+
+        Context 'With the gist on the pipeline' {
+            $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+            It 'Should be there' {
+                { $gist | Get-GitHubGist } | Should -Not -Throw
+            }
+
+            It 'Should remove the gist successfully' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+
+            It 'Should be removed' {
+                { $gist | Get-GitHubGist } | Should -Throw
+            }
+        }
+    }
+
+    Describe 'Copy-GitHubGist' {
+        BeforeAll {
+            $originalGist = Get-GitHubGist -Gist '1169852' # octocat/test.cs
+        }
+
+        Context 'By parameters' {
+            $gist = Copy-GitHubGist -Gist $originalGist.id
+            It 'Should have been forked' {
+                $gist.files.Count | Should -Be $originalGist.files.Count
+                foreach ($file in $gist.files)
+                {
+                    $originalFile = $originalGist.files |
+                        Where-Object { $_.filename -eq $file.filename }
+                    $file.filename | Should -Be $originalFile.filename
+                    $file.size | Should -Be $originalFile.size
+                }
+            }
+
+            It 'Should have the expected additional type and properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.GistSummary'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should be removed' {
+                { Remove-GitHubGist -Gist $gist.id -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'Gist on the pipeline' {
+            $gist = $originalGist | Copy-GitHubGist
+            It 'Should have been forked' {
+                $gist.files.Count | Should -Be $originalGist.files.Count
+                foreach ($file in $gist.files)
+                {
+                    $originalFile = $originalGist.files |
+                        Where-Object { $_.filename -eq $file.filename }
+                    $file.filename | Should -Be $originalFile.filename
+                    $file.size | Should -Be $originalFile.size
+                }
+            }
+
+            It 'Should have the expected additional type and properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.GistSummary'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should be removed' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+    }
+
+    Describe 'Add/Remove/Set/Test-GitHubGistStar' {
+        BeforeAll {
+            $gist = New-GitHubGist -FileName 'sample.txt' -Content 'Sample text'
+        }
+
+        AfterAll {
+            $gist | Remove-GitHubGist -Force
+        }
+
+        Context 'With parameters' {
+            $starred = Test-GitHubGistStar -Gist $gist.id
+            It 'Should not be starred yet' {
+                $starred | Should -BeFalse
+            }
+
+            Add-GitHubGistStar -Gist $gist.id
+            $starred = Test-GitHubGistStar -Gist $gist.id
+            It 'Should now be starred' {
+                $starred | Should -BeTrue
+            }
+
+            Remove-GitHubGistStar -Gist $gist.id
+            $starred = Test-GitHubGistStar -Gist $gist.id
+            It 'Should no longer be starred' {
+                $starred | Should -BeFalse
+            }
+
+            Set-GitHubGistStar -Gist $gist.id -Star
+            $starred = Test-GitHubGistStar -Gist $gist.id
+            It 'Should now be starred' {
+                $starred | Should -BeTrue
+            }
+
+            Set-GitHubGistStar -Gist $gist.id
+            $starred = Test-GitHubGistStar -Gist $gist.id
+            It 'Should no longer be starred' {
+                $starred | Should -BeFalse
+            }
+        }
+
+        Context 'With the gist on the pipeline' {
+            $starred = $gist | Test-GitHubGistStar
+            It 'Should not be starred yet' {
+                $starred | Should -BeFalse
+            }
+
+            $gist | Add-GitHubGistStar
+            $starred = $gist | Test-GitHubGistStar
+            It 'Should now be starred' {
+                $starred | Should -BeTrue
+            }
+
+            $gist | Remove-GitHubGistStar
+            $starred = $gist | Test-GitHubGistStar
+            It 'Should no longer be starred' {
+                $starred | Should -BeFalse
+            }
+
+            $gist | Set-GitHubGistStar -Star
+            $starred = $gist | Test-GitHubGistStar
+            It 'Should now be starred' {
+                $starred | Should -BeTrue
+            }
+
+            $gist | Set-GitHubGistStar
+            $starred = $gist | Test-GitHubGistStar
+            It 'Should no longer be starred' {
+                $starred | Should -BeFalse
+            }
+        }
+    }
+
+    Describe 'New-GitHubGist' {
+        Context 'By content' {
+            BeforeAll {
+                $content = 'This is my content'
+                $filename = 'sample.txt'
+                $description = 'my description'
+            }
+
+            $gist = New-GitHubGist -FileName $filename -Content $content -Public
+            It 'Should have the expected result' {
+                $gist.public | Should -BeTrue
+                $gist.description | Should -BeNullOrEmpty
+                $gist.files.$filename.content | Should -Be $content
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should be removed' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+
+            $gist = New-GitHubGist -FileName $filename -Content $content -Description $description -Public:$false
+            It 'Should have the expected result' {
+                $gist.public | Should -BeFalse
+                $gist.description | Should -Be $description
+                $gist.files.$filename.content | Should -Be $content
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should error if file starts with "gistfile"' {
+                { New-GitHubGist -FileName 'gistfile1' -Content $content } | Should -Throw
+            }
+
+            It 'Should be removed' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'By files' {
+            BeforeAll {
+                $tempFile = New-TemporaryFile
+                $fileA = "$($tempFile.FullName).ps1"
+                Move-Item -Path $tempFile -Destination $fileA
+                $fileAName = (Get-Item -Path $fileA).Name
+                $fileAContent = 'fileA content'
+                Out-File -FilePath $fileA -InputObject $fileAContent -Encoding utf8
+
+                $tempFile = New-TemporaryFile
+                $fileB = "$($tempFile.FullName).txt"
+                Move-Item -Path $tempFile -Destination $fileB
+                $fileBName = (Get-Item -Path $fileB).Name
+                $fileBContent = 'fileB content'
+                Out-File -FilePath $fileB -InputObject $fileBContent -Encoding utf8
+
+                $description = 'my description'
+            }
+
+            AfterAll {
+                @($fileA, $fileB) | Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            $gist = New-GitHubGist -File @($fileA, $fileB) -Public
+            It 'Should have the expected result' {
+                $gist.public | Should -BeTrue
+                $gist.description | Should -BeNullOrEmpty
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAContent
+                $gist.files.$fileBName.content.Trim() | Should -Be $fileBContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should be removed' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+
+            $gist = New-GitHubGist -File @($fileA, $fileB) -Description $description -Public:$false
+            It 'Should have the expected result' {
+                $gist.public | Should -BeFalse
+                $gist.description | Should -Be $description
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAContent
+                $gist.files.$fileBName.content.Trim() | Should -Be $fileBContent
+            }
+
+            It 'Should be removed' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+
+            $gist = @($fileA, $fileB) | New-GitHubGist -Description $description -Public:$false
+            It 'Should have the expected result with the files on the pipeline' {
+                $gist.public | Should -BeFalse
+                $gist.description | Should -Be $description
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAContent
+                $gist.files.$fileBName.content.Trim() | Should -Be $fileBContent
+            }
+        }
+    }
+
+    Describe 'Set-GitHubGist' {
+        BeforeAll {
+            $fileAName = 'foo.txt'
+            $fileAContent = 'foo content'
+            $fileAUpdatedContent = 'foo updated content'
+            $fileANewName = 'gamma.txt'
+
+            $fileBName = 'bar.txt'
+            $fileBContent = 'bar content'
+            $fileBUpdatedContent = 'bar updated content'
+
+            $fileCName = 'alpha.txt'
+            $fileCContent = 'alpha content'
+            $fileCUpdatedContent = 'alpha updated content'
+            $fileCNewName = 'gamma.txt'
+
+            $tempFile = New-TemporaryFile
+            $fileD = "$($tempFile.FullName).txt"
+            Move-Item -Path $tempFile -Destination $fileD
+            $fileDName = (Get-Item -Path $fileD).Name
+            $fileDContent = 'fileD content'
+            Out-File -FilePath $fileD -InputObject $fileDContent -Encoding utf8
+            $fileDUpdatedContent = 'fileD updated content'
+
+            $description = 'my description'
+            $updatedDescription = 'updated description'
+        }
+
+        AfterAll {
+            @($fileD) | Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+        }
+
+        Context 'With parameters' {
+            BeforeAll {
+                $gist = New-GitHubGist -FileName $fileAName -Content $fileAContent -Description $description
+            }
+
+            AfterAll {
+                $gist | Remove-GitHubGist -Force
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $fileBName -Content $fileBContent
+            It 'Should be in the expected, original state' {
+                $gist.description | Should -Be $description
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$fileAName.content | Should -Be $fileAContent
+                $gist.files.$fileBName.content | Should -Be $fileBContent
+            }
+
+            $setParams = @{
+                Gist = $gist.id
+                Description = $updatedDescription
+                Delete = @($fileBName)
+                Update = @{
+                    $fileAName = @{
+                        fileName = $fileANewName
+                        content = $fileAUpdatedContent
+                    }
+                    $fileCName = @{ content = $fileCContent }
+                    $fileDName = @{ filePath = $fileD }
+                }
+            }
+
+            $gist = Set-GitHubGist @setParams -Force
+            It 'Should have been properly updated' {
+                $gist.description | Should -Be $updatedDescription
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 3
+                $gist.files.$fileAName | Should -BeNullOrEmpty
+                $gist.files.$fileANewName.content | Should -Be $fileAContent
+                $gist.files.$fileBName | Should -BeNullOrEmpty
+                $gist.files.$fileCName.content | Should -Be $fileCContent
+                $gist.files.$fileDName.content.Trim() | Should -Be $fileDContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $setParams = @{
+                Gist = $gist.id
+                Update = @{
+                    $fileDName = @{
+                        content = 'updated content'
+                        filePath = $fileD
+                    }
+                }
+            }
+
+            It 'Should throw if updating a file with both a filePath and content' {
+                { $gist = Set-GitHubGist @setParams } | Should -Throw
+            }
+        }
+
+        Context 'With the gist on the pipeline' {
+            BeforeAll {
+                $gist = New-GitHubGist -FileName $fileAName -Content $fileAContent -Description $description
+            }
+
+            AfterAll {
+                $gist | Remove-GitHubGist -Force
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $fileBName -Content $fileBContent
+            It 'Should be in the expected, original state' {
+                $gist.description | Should -Be $description
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$fileAName.content | Should -Be $fileAContent
+                $gist.files.$fileBName.content | Should -Be $fileBContent
+            }
+
+            $setParams = @{
+                Description = $updatedDescription
+                Delete = @($fileBName)
+                Update = @{
+                    $fileAName = @{
+                        fileName = $fileANewName
+                        content = $fileAUpdatedContent
+                    }
+                    $fileCName = @{ content = $fileCContent }
+                    $fileDName = @{ filePath = $fileD }
+                }
+            }
+
+            $gist = $gist | Set-GitHubGist @setParams -Confirm:$false
+            It 'Should have been properly updated' {
+                $gist.description | Should -Be $updatedDescription
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 3
+                $gist.files.$fileAName | Should -BeNullOrEmpty
+                $gist.files.$fileANewName.content | Should -Be $fileAContent
+                $gist.files.$fileBName | Should -BeNullOrEmpty
+                $gist.files.$fileCName.content | Should -Be $fileCContent
+                $gist.files.$fileDName.content.Trim() | Should -Be $fileDContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $setParams = @{
+                Update = @{
+                    $fileDName = @{
+                        content = 'updated content'
+                        filePath = $fileD
+                    }
+                }
+            }
+
+            It 'Should throw if updating a file with both a filePath and content' {
+                { $gist = $gist | Set-GitHubGist @setParams } | Should -Throw
+            }
+        }
+    }
+
+    Describe 'Set-GitHubGistFile' {
+        BeforeAll {
+            $origFileName = 'foo.txt'
+            $origContent = 'original content'
+            $updatedOrigContent = 'updated content'
+
+            $newFileName = 'bar.txt'
+            $newContent = 'new content'
+
+            $gist = New-GitHubGist -FileName $origFileName -Content $origContent
+        }
+
+        AfterAll {
+            $gist | Remove-GitHubGist -Force
+        }
+
+        Context 'By content with parameters' {
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $origFileName -Content $updatedOrigContent
+            It 'Should have the expected result' {
+                $gist.files.$origFileName.content | Should -Be $updatedOrigContent
+                $gist.files.$newFileName | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $newFileName -Content $newContent
+            It 'Should have the expected result' {
+                $gist.files.$origFileName.content | Should -Be $updatedOrigContent
+                $gist.files.$newFileName.content | Should -Be $newContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $origFileName -Content $origContent
+            It 'Should remove the new file' {
+                { $gist | Remove-GitHubGistFile -FileName $newFileName -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'By content with the gist on the pipeline' {
+            $gist = $gist | Set-GitHubGistFile -FileName $origFileName -Content $updatedOrigContent
+            It 'Should have the expected result' {
+                $gist.files.$origFileName.content | Should -Be $updatedOrigContent
+                $gist.files.$newFileName | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = $gist | Set-GitHubGistFile -FileName $newFileName -Content $newContent
+            It 'Should have the expected result' {
+                $gist.files.$origFileName.content | Should -Be $updatedOrigContent
+                $gist.files.$newFileName.content | Should -Be $newContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $origFileName -Content $origContent
+            It 'Should remove the new file' {
+                { $gist | Remove-GitHubGistFile -FileName $newFileName -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'By files with parameters' {
+            BeforeAll {
+                $tempFile = New-TemporaryFile
+                $fileA = "$($tempFile.FullName).txt"
+                Move-Item -Path $tempFile -Destination $fileA
+                $fileAName = (Get-Item -Path $fileA).Name
+                $fileAContent = 'fileA content'
+                Out-File -FilePath $fileA -InputObject $fileAContent -Encoding utf8
+                $fileAUpdatedContent = 'fileA content updated'
+            }
+
+            AfterAll {
+                @($fileA) | Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -File $fileA
+            It 'Should have the expected result' {
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$origFileName.content | Should -Be $origContent
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            Out-File -FilePath $fileA -InputObject $fileAUpdatedContent -Encoding utf8
+            $gist = Set-GitHubGistFile -Gist $gist.id -File $fileA
+            It 'Should have the expected result' {
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$origFileName.content | Should -Be $origContent
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAUpdatedContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $origFileName -Content $origContent
+            It 'Should remove the new file' {
+                { $gist | Remove-GitHubGistFile -FileName $fileAName -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'By files with the gist on the pipeline' {
+            BeforeAll {
+                $tempFile = New-TemporaryFile
+                $fileA = "$($tempFile.FullName).txt"
+                Move-Item -Path $tempFile -Destination $fileA
+                $fileAName = (Get-Item -Path $fileA).Name
+                $fileAContent = 'fileA content'
+                Out-File -FilePath $fileA -InputObject $fileAContent -Encoding utf8
+                $fileAUpdatedContent = 'fileA content updated'
+            }
+
+            AfterAll {
+                @($fileA) | Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            $gist = $gist | Set-GitHubGistFile -File $fileA
+            It 'Should have the expected result' {
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$origFileName.content | Should -Be $origContent
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            Out-File -FilePath $fileA -InputObject $fileAUpdatedContent -Encoding utf8
+            $gist = $gist | Set-GitHubGistFile -File $fileA
+            It 'Should have the expected result' {
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$origFileName.content | Should -Be $origContent
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAUpdatedContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $origFileName -Content $origContent
+            It 'Should remove the new file' {
+                { $gist | Remove-GitHubGistFile -FileName $fileAName -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'By files with the file on the pipeline' {
+            BeforeAll {
+                $tempFile = New-TemporaryFile
+                $fileA = "$($tempFile.FullName).txt"
+                Move-Item -Path $tempFile -Destination $fileA
+                $fileAName = (Get-Item -Path $fileA).Name
+                $fileAContent = 'fileA content'
+                Out-File -FilePath $fileA -InputObject $fileAContent -Encoding utf8
+                $fileAUpdatedContent = 'fileA content updated'
+            }
+
+            AfterAll {
+                @($fileA) | Remove-Item -Force -ErrorAction SilentlyContinue | Out-Null
+            }
+
+            $gist = $fileA | Set-GitHubGistFile -Gist $gist.id
+            It 'Should have the expected result' {
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$origFileName.content | Should -Be $origContent
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            Out-File -FilePath $fileA -InputObject $fileAUpdatedContent -Encoding utf8
+            $gist = $fileA | Set-GitHubGistFile -Gist $gist.id
+            It 'Should have the expected result' {
+                ($gist.files | Get-Member -Type NoteProperty).Count | Should -Be 2
+                $gist.files.$origFileName.content | Should -Be $origContent
+                $gist.files.$fileAName.content.Trim() | Should -Be $fileAUpdatedContent
+            }
+
+            It 'Should have the expected type and additional properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            $gist = Set-GitHubGistFile -Gist $gist.id -FileName $origFileName -Content $origContent
+            It 'Should remove the new file' {
+                { $gist | Remove-GitHubGistFile -FileName $fileAName -Force } | Should -Not -Throw
+            }
+        }
+    }
+
+    Describe 'Rename-GitHubGistFile' {
+        BeforeAll {
+            $originalName = 'foo.txt'
+            $newName = 'bar.txt'
+            $content = 'sample content'
+        }
+
+        Context 'With parameters' {
+            $gist = New-GitHubGist -FileName $originalName -Content $content
+            It 'Should have the expected file' {
+                $gist.files.$originalName.content | Should -Be $content
+                $gist.files.$newName | Should -BeNullOrEmpty
+            }
+
+            $gist = Rename-GitHubGistFile -Gist $gist.id -FileName $originalName -NewName $newName
+            It 'Should have been renamed' {
+                $gist.files.$originalName | Should -BeNullOrEmpty
+                $gist.files.$newName.content | Should -Be $content
+            }
+
+            It 'Should have the expected additional type and properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should successfully remove the gist' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'With the gist on the pipeline' {
+            $gist = New-GitHubGist -FileName $originalName -Content $content
+            It 'Should have the expected file' {
+                $gist.files.$originalName.content | Should -Be $content
+                $gist.files.$newName | Should -BeNullOrEmpty
+            }
+
+            $gist = $gist | Rename-GitHubGistFile -FileName $originalName -NewName $newName
+            It 'Should have been renamed' {
+                $gist.files.$originalName | Should -BeNullOrEmpty
+                $gist.files.$newName.content | Should -Be $content
+            }
+
+            It 'Should have the expected additional type and properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should successfully remove the gist' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+    }
+
+    Describe 'Remove-GitHubGistFile' {
+        BeforeAll {
+            $fileName = 'sample.txt'
+            $content = 'sample'
+        }
+
+        Context 'With parameters' {
+            $gist = New-GitHubGist -FileName $fileName -Content $content
+            It 'Should have the expected file' {
+                $gist.files.$fileName | Should -Not -BeNullOrEmpty
+            }
+
+            $gist = Remove-GitHubGistFile -Gist $gist.id -FileName $fileName -Force
+            It 'Should have been removed' {
+                $gist.files.$fileName | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected additional type and properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should successfully remove the gist' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+
+        Context 'With the gist on the pipeline' {
+            $gist = New-GitHubGist -FileName $fileName -Content $content
+            It 'Should have the expected file' {
+                $gist.files.$fileName | Should -Not -BeNullOrEmpty
+            }
+
+            $gist = $gist | Remove-GitHubGistFile -FileName $fileName -Confirm:$false
+            It 'Should have been removed' {
+                $gist.files.$fileName | Should -BeNullOrEmpty
+            }
+
+            It 'Should have the expected additional type and properties' {
+                $gist.PSObject.TypeNames[0] | Should -Be 'GitHub.Gist'
+                $gist.GistId | Should -Be $gist.id
+                $gist.owner.PSObject.TypeNames[0] | Should -Be 'GitHub.User'
+            }
+
+            It 'Should successfully remove the gist' {
+                { $gist | Remove-GitHubGist -Force } | Should -Not -Throw
+            }
+        }
+    }
+}
+finally
+{
+    if (Test-Path -Path $script:originalConfigFile -PathType Leaf)
+    {
+        # Restore the user's configuration to its pre-test state
+        Restore-GitHubConfiguration -Path $script:originalConfigFile
+        $script:originalConfigFile = $null
+    }
+}
diff --git a/USAGE.md b/USAGE.md
index 8e93a1c5..456c0186 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -97,6 +97,18 @@
         *   [Create a release asset](#create-a-release-asset)
         *   [Update a release asset](#update-a-release-asset)
         *   [Remove a release asset](#remove-a-release-asset)
+    *   [Gists](#gists)
+        *   [Getting gists](#getting-gists)
+        *   [Download a gist](#download-a-gist)
+        *   [Fork a gist](#fork-a-gist)
+        *   [Creating a gist](#creating-a-gist)
+        *   [Removing a gist](#removing-a-gist)
+        *   [Updating a gist](#updating-a-gist)
+        *   [Starring a gist](#starring-a-gist)
+        *   [Getting gist comments](#getting-gist-comments)
+        *   [Adding a gist comment](#adding-a-gist-comment)
+        *   [Changing a gist comment](#changing-a-gist-comment)
+        *   [Removing a gist comment](#removing-a-gist-comment)
     *   [Advanced](#advanced)
         *   [Migrating blog comments to GitHub issues](#migrating-blog-comments-to-github-issues)
 
@@ -869,6 +881,169 @@ or with pipelining...
 
 ```powershell
 $asset | Remove-GitHubReleaseAsset -force
+
+----------
+
+### Gists
+
+#### Getting gists
+```powershell
+# There are many options here:
+
+# 1. Getting all gists for the current authenticated user:
+Get-GitHubGist
+
+# 1b. Getting all gists for the current authenticated user that were updated in the past 6 days.
+Get-GitHubGist -Since ((Get-Date).AddDays(-6))
+
+# 2. Get all starred gists for the current authenticated user
+Get-GitHubGist -Starred
+
+# 3. Get all public gists for a specific user
+Get-GitHubGist -UserName 'octocat'
+
+# 4. Get all public gists (well, the first 3000):
+Get-GitHubGist -Public
+
+# 5. Get a specific gist
+Get-GitHubGist -Gist '6cad326836d38bd3a7ae'
+
+# 5a. List all commits for a specific gist
+Get-GitHubGist -Gist '6cad326836d38bd3a7ae' -Commits
+
+# 5b. Get a gist at a specific commit (Sha)
+Get-GitHubGist -Gist '6cad326836d38bd3a7ae' -Sha 'de5b9b59d1f28206e8d646c7c8025e9809d0ed73'
+
+# 5c. Get all of the forks for a gist
+Get-GitHubGist -Gist '6cad326836d38bd3a7ae' -Forks
+```
+
+#### Download a gist
+```powershell
+Get-GitHubGist -Gist '6cad326836d38bd3a7ae' -Path 'c:\users\octocat\downloads\gist\'
+```
+
+#### Fork a gist
+```powershell
+Fork-GitHubGist -Gist '6cad326836d38bd3a7ae'
+```
+
+#### Creating a gist
+```powershell
+# You can create a gist by specifying a single file's content in-line...
+New-GitHubGist -FileName 'foo.txt' -Content 'foo content'
+
+# or by providing one or more files that should be part of the gist
+New-GitHubGist -File @('c:\files\foo.txt', 'c:\files\bar.txt')
+@('c:\files\foo.txt', 'c:\files\bar.txt') | New-GitHubGist
+```
+
+#### Removing a gist
+```powershell
+Remove-GitHubGist -Gist '6cad326836d38bd3a7ae'
+```
+
+#### Updating a gist
+```powershell
+$gist = New-GitHubGist -FileName 'foo.txt' -Content 'content'
+
+# The main method to use is Set-GitHubGist, however it is quite complicated.
+$params = @{
+    Description = 'new description' # modifies the description of the gist
+    Update = @{
+        'foo.txt' = @{
+            fileName = 'alpha.txt' # Will rename foo.txt -> alpha.txt
+            content = 'updated content' # and will also update its content
+        }
+        'bar.txt' = @{
+            filePath = 'c:\files\bar.txt' # Will upload the content of bar.txt to the gist.
+        }
+    }
+    Delete = @('bar.txt')
+    Force = $true # avoid confirmation prompting due to the deletion
+}
+
+Set-GitHubGist -Gist $gist.id @params
+
+# Therefore, you can use simpler helper methods to accomplish atomic tasks
+Set-GistHubGistFile -Gist $gist.id -FileName 'foo.txt' -Content 'updated content'
+
+# This will update the text in the existing file 'foo.txt' and add the file 'bar.txt'
+$gist | Set-GitHubGistFile -File ('c:\files\foo.txt', 'c:\files\bar.txt')
+
+Rename-GistHubGistFile -Gist $gist.id -FileName 'foo.txt' -NewName 'bar.txt'
+
+$gist | Remove-GitHubGistFile -FileName 'bar.txt' -Force
+
+```
+
+#### Starring a gist
+```powershell
+$gistId = '6cad326836d38bd3a7ae'
+
+# All of these options will star the same gist
+Star-GitHubGist -Gist $gistId
+Add-GitHubGistStar -Gist $gistId
+Set-GitHubGistStar -Gist $gistId -Star
+Get-GitHubGist -Gist $gistId | Star-GitHubGist
+
+# All of these options will unstar the same gist
+Unstar-GitHubGist -Gist $gistId
+Remove-GitHubGistStar -Gist $gistId
+Set-GitHubGistStar -Gist $gistId
+Set-GitHubGistStar -Gist $gistId -Star:$false
+Get-GitHubGist -Gist $gistId | Unstar-GitHubGist
+
+# All of these options will tell you if you have starred a gist
+Test-GitHubGistStar -Gist $gistId
+Get-GitHubGist -Gist $gistId | Test-GitHubGistStar
+```
+
+#### Getting gist comments
+```powershell
+$gistId = '6cad326836d38bd3a7ae'
+$commentId = 1507813
+
+# You can get all comments for a gist with any of these options:
+Get-GitHubGistComment -Gist $gistId
+Get-GitHubGist -Gist $gistId | Get-GitHubGistComment
+
+# You can retrieve an individual comment like this:
+Get-GitHubGistComment -Gist $gistId -Comment $commentId
+```
+
+#### Adding a gist comment
+```powershell
+$gistId = '6cad326836d38bd3a7ae'
+
+New-GitHubGistComment -Gist $gistId -Body 'Hello World'
+
+# or with the pipeline
+Get-GitHubGist -Gist $gistId | New-GitHubGistComment -Body 'Hello World'
+```
+
+#### Changing a gist comment
+```powershell
+$gistId = '6cad326836d38bd3a7ae'
+$commentId = 1507813
+
+Set-GitHubGistComment -Gist $gistId -Comment $commentId -Body 'Updated comment'
+
+# or with the pipeline
+Get-GitHubGist -Gist $gistId -Comment $commentId | Set-GitHubGistComment -Body 'Updated comment'
+```
+
+#### Removing a gist comment
+```powershell
+$gistId = '6cad326836d38bd3a7ae'
+$commentId = 1507813
+
+# If you don't specify -Force, it will prompt for confirmation before it will delete the comment
+
+Remove-GitHubGistComment -Gist $gistId -Comment $commentId -Force
+
+# or with the pipeline
+Get-GitHubGist -Gist $gistId -Comment $commentId | Remove-GitHubGistComment -Force
 ```
 
 ----------