powershell-pulp.psm1

#Requires -Version 3.0
if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertsPolicy').Type){
  Add-Type -Path $PSScriptRoot\lib\*.cs
  [System.Net.ServicePointManager]::CertificatePolicy =
    New-Object TrustAllCertsPolicy
}

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpLocalConfig {
  [Cmdletbinding()]
  Param(
    [Parameter(Mandatory=$false)]  [string] $File = '~\.pulp\admin.json',
    [Parameter(Mandatory=$false)]  [switch] $Server,
    [Parameter(Mandatory=$false)]  [switch] $Port,
    [Parameter(Mandatory=$false)]  [switch] $Protocol,
    [Parameter(Mandatory=$false)]  [switch] $Username,
    [Parameter(Mandatory=$false)]  [switch] $Password
  ) #end Param
  $defaults = @{'port'='443';'protocol'='https';'username'=$env:USERNAME}
  $settings = New-Object -TypeName PSCustomObject
  $readSettings = New-Object -TypeName PSCustomObject
  $params = $PSBoundParameters.GetEnumerator()|
            Where-Object {($_.Key -ne 'File')}
  
  if (Test-Path $File){
    try {
      $readSettings = Get-Content -Raw '~\.pulp\admin.json' | ConvertFrom-Json
    } catch {}
  }
  foreach ($parameter in $params){
    $setting = $parameter.Key.ToLower()
    $value = $parameter.Value
    if ($value){
      if ($readSettings.$setting) { 
        Add-Member -InputObject $settings -MemberType NoteProperty `
                   -Name $setting -Value $readSettings.$setting
      }
      elseif ($defaults.$setting) {
        Add-Member -InputObject $settings -MemberType NoteProperty `
                   -Name $setting -Value $defaults.$setting}
      else {
       Add-Member -InputObject $settings -MemberType NoteProperty `
                  -Name $setting -Value (Read-Host "$setting")
      }
    }
  } 
  if ($params.count -eq 0){
    foreach ($default in $defaults.GetEnumerator()){
      $setting = $default.Name
      $value = $default.Value
      Add-Member -InputObject $settings -MemberType NoteProperty `
                 -Name $setting -Value $value -Force
    }
    $readSettings.PSObject.Properties |
    foreach-object {
      $setting = $_.Name
      $value = $_.Value
      Add-Member -InputObject $settings -MemberType NoteProperty `
                 -Name $setting -Value $value -Force
    }
  }
  Return $settings
} #end Function Get-PulpLocalConfig

# .ExternalHelp powershell-pulp-help.xml
Function Set-PulpLocalConfig
{
  [Cmdletbinding()]
  Param(
    [Parameter(Mandatory=$false)]        [string]  $File = '~\.pulp\admin.json',
    [Parameter(Mandatory=$false)]        [switch]  $Replace,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Object")] [object]  $Settings,
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")][string] $Server,
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")][string] $Port,
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")][string] $Protocols,               
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")][string] $Username,
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")][string] $Password
  ) #end Param
  If ($Settings){
    $newSettings = New-Object -TypeName PSCustomObject
      if (!$Replace){
      $readSettings = Get-PulpLocalConfig -File $File
      $readSettings.PSObject.Properties | 
      foreach-object {
        Add-Member -InputObject $newSettings -MemberType NoteProperty `
                    -Name $_.Name -Value $_.Value
      }
    }
    $Settings.PSObject.Properties | 
    foreach-object {
      $setting = $_.Name
      $value = $_.Value
      Add-Member -InputObject $newSettings -MemberType NoteProperty `
                 -Name $setting -Value $value -Force

    }
    $null = (New-Item -ItemType Directory -Force -Path (Split-Path $File))
    $newSettings | ConvertTo-JSON | Out-File $File
    Get-PulpLocalConfig -File $File
  } 
  else {
    $params = $PSBoundParameters.GetEnumerator()|
              Where-Object {($_.Key -ne 'File' -and
                             $_.Key -ne 'Settings' -and
                             $_.Key -ne 'Replace')}
    $Settings = New-Object -TypeName PSCustomObject
    foreach ($parameter in $params){
      $setting = $parameter.Key.ToLower()
      $value = $parameter.Value
        if ($value){
          Add-Member -InputObject $Settings -MemberType NoteProperty `
                     -Name $setting -Value $value
        }
    }
    Set-PulpLocalConfig -File $File -Settings $Settings -Replace:$Replace
  }
} #end Function Set-PulpLocalConfig

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpCertificate
{
 [Cmdletbinding()]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     = 
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false)] [string] $Username =
                                       (Get-PulpLocalConfig -Username).Username,
    [Parameter(Mandatory=$false)] [string] $Password
  ) #end param

  $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/actions/login/"
  $certFriendlyName = "Pulp on $server"
  $certStorePath = "Cert:\CurrentUser\My"

  $storedCertificates = (Get-ChildItem $certStorePath |
                         Where-Object {$_.FriendlyName -eq $certFriendlyName} |
                         Where-Object {$_.NotAfter -gt (Get-Date)} |
                         Sort-Object NotAfter -Descending)
  if ($storedCertificates.Count -gt 0){
    return $storedCertificates[0]
  } else {
    $config = Get-PulpLocalConfig
    if ($config.password) {
      $Password = $config.password  
    }
    while (!$authResponse){
      if (!$Password){
        $credential = Get-Credential -user $Username -Message $certFriendlyName
        $Password = $credential.GetNetworkCredential().password
        $Username = $credential.UserName
      }
      $base64Cred = [System.Convert]::ToBase64String(
        [Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $Username,$Password)))
      try {
        $authResponse = Invoke-RestMethod -Uri $uri -Method Post `
                        -Headers @{Authorization=("Basic {0}" -f $base64Cred)} `
                        -ErrorAction Continue
      } catch {
        $Password = $null
      }
    }
    $certBytes = [System.Convert]::FromBase64String(
      $authResponse.certificate.Substring(
        28, $authResponse.certificate.Length - 55))
    $keyBytes = [System.Convert]::FromBase64String(
      $authResponse.key.Substring(32, $authResponse.key.Length-63))
    $decodedKey = [PowershellPulp.Crypto]::DecodeRsaPrivateKey($keyBytes)
    $certificate = New-Object `
    System.Security.Cryptography.X509Certificates.X509Certificate2(
      $certBytes,'')
    $certificate.FriendlyName = $certFriendlyName
    $certificate.PrivateKey = $decodedKey
    $certStore = Get-Item $certStorePath
    $certStore.Open('ReadWrite')
    $certStore.Add($certificate)
    # Recursion!
    return (Get-PulpCertificate -Server $Server -Port $Port `
                                -Protocol $Protocol -Username $Username `
                                -Password $Password)
  }
} #end function Get-PulpCertificate

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpRpmRepo {
  [CmdletBinding()]param(                           
                                                     [string]  ${Server},
                                                     [int]     ${Port},
                                                     [string]  ${Protocol},
    [Parameter(Position=0, ValueFromPipeline=$true)] [string[]]${Id}
  )
  Begin {
    try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Get-PulpRepo', [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'rpm'}
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    catch { throw }
  }
  Process {
    try {
      $steppablePipeline.Process($_)
    }
    catch {
      throw
    }
  }
  End {
    try {
      $steppablePipeline.End()
    }
    catch {
      throw
    }
  }
} #end function Get-PulpRpmRepo

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpIsoRepo {
  [CmdletBinding()]param(                           
                                                     [string]  ${Server},
                                                     [int]     ${Port},
                                                     [string]  ${Protocol},
    [Parameter(Position=0, ValueFromPipeline=$true)] [string[]]${Id}
  )
  Begin {
    try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Get-PulpRepo', [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'iso'}
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    catch { throw }
  }
  Process {
    try {
      $steppablePipeline.Process($_)
    }
    catch {
      throw
    }
  }
  End {
    try {
      $steppablePipeline.End()
    }
    catch {
      throw
    }
  }
} #end function Get-PulpIsoRepo

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpPuppetRepo {
  [CmdletBinding()]param(                           
                                                     [string]  ${Server},
                                                     [int]     ${Port},
                                                     [string]  ${Protocol},
    [Parameter(Position=0, ValueFromPipeline=$true)] [string[]]${Id}
  )
  Begin {
    try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Get-PulpRepo', [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'puppet'}
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    catch { throw }
  }
  Process {
    try {
      $steppablePipeline.Process($_)
    }
    catch {
      throw
    }
  }
  End {
    try {
      $steppablePipeline.End()
    }
    catch {
      throw
    }
  }
} #end function Get-PulpPuppetRepo

Function Get-PulpRepo {
 [Cmdletbinding()]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true)] [string[]]$Id       = "*",
    [Parameter(Mandatory=$true)] [string] $Type) #end param
  Begin {
    $uri = "${Protocol}://${Server}:${Port}" +
    "/pulp/api/v2/repositories/?details=true&importers=true&distributors=true"
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    $repos = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
  }
  Process {
    foreach ($item in $Id) {
      $repos | Where-Object {($_.notes.'_repo-type' -eq  "${Type}-repo") -and
                             ($_.id -like $item)}
     }
  } #end Process
} #end function Get-PulpRepo

# .ExternalHelp powershell-pulp-help.xml
Function New-PulpRpmRepo
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Object")] [object[]]$Repo,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string] $Id,
                                               #REST: id
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $DisplayName,
                                               #REST: display_name
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $Description,
                                               #REST: description
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $Note,
                                               #REST: notes
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $Feed,
                 #REST: /importers/: importer_config: feed
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [bool]   $Validate,
                 #REST: /importers/: importer_config: validate
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $Skip,
                 #REST: /importers/: importer_config: type_skip_list
                 # (comma list, valid types: "rpm, drpm, distribution, erratum")
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $FeedCaCert,
                 #REST: /importers/: importer_config: ssl_ca_cert
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [bool]   $VerifyFeedSsl,
                 #REST: /importers/: importer_config: ssl_validation
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $FeedCert,
                 #REST: /importers/: importer_config: ssl_client_cert
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $FeedKey,
                 #REST: /importers/: importer_config: ssl_client_key
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $ProxyHost,
                 #REST: /importers/: importer_config: proxy_host
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $ProxyPort,
                 #REST: /importers/: importer_config: proxy_port
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $ProxyUser,
                 #REST: /importers/: importer_config: proxy_username
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $ProxyPass,
                 #REST: /importers/: importer_config: proxy_password
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $BasicauthUser,
                 #REST: /importers/: importer_config: basic_auth_username
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $BasicauthPass,
                 #REST: /importers/: importer_config: basic_auth_password
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [int]    $MaxDownloads,
                 #REST: /importers/: importer_config: max_downloads
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [int]    $MaxSpeed,
                 #REST: /importers/: importer_config: max_speed
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [bool]   $RemoveMissing,
                 #REST: /importers/: importer_config: remove_missing
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [int]    $RetainOldCount,
                 #REST: /importers/: importer_config: retain_old_count
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $RelativeUrl,
           #REST: /distributors/: distributor_config: relative_url
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [bool]   $ServeHttp        = $false,
           #REST: /distributors/: distributor_config: http
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [bool]   $ServeHttps        = $true,
           #REST: /distributors/: distributor_config: https
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $AutoPublish       = $true,
                               #REST: /distributors/: auto_publish
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $ChecksumType,
           #REST: /distributors/: distributor_config: checksum_type
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $GpgKey,
           #REST: /distributors/: distributor_config: gpgkey
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [bool]   $GenerateSqlite,
           #REST: /distributors/: distributor_config: generate_sqlite
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $HostCa,
           #REST: /distributors/: distributor_config: https_ca
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $AuthCa,
           #REST: /distributors/: distributor_config: auth_ca
    [Parameter(Mandatory=$false,
               ParameterSetName="Strings")] [string] $AuthCert
           #REST: /distributors/: distributor_config: auth_cert
    ) #end Param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    If (!$DisplayName){
      $displayNameFromId = $true
    }
    If ($feed -and !$RelativeUrl){
      $relativeUrlFromFeed = $true
    }
    If (!$RelativeUrl){
      $relativeUrlFromId = $true
    }
  } #end Begin
  Process {
    If ($Repo) { # Object-based parameter
      foreach ($repoItem in $Repo){
        # Create basic repo
        $idItem = $repoItem.id
        $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/repositories/"
        $body = $repoItem | Select-Object id,display_name,description,notes |
                ConvertTo-Json
        $result = Invoke-RestMethod -Uri $uri -Method Post `
                                    -Certificate $cert -body $body    
        # Build and attach importer config
        $uri = "${Protocol}://${Server}:${Port}" +
                "/pulp/api/v2/repositories/${idItem}/importers/"
        foreach ($importer in $repoItem.importers) {
          $body = $importer | Select-Object importer_type_id,
                                            @{Name='importer_config';
                                              Expression={$_.config}} |
                              ConvertTo-Json
          $result = Invoke-RestMethod -Uri $uri -Method Post `
                                     -Certificate $cert -body $body
          # Wait for attach to complete
          $href = $result.spawned_tasks._href
          $uri = "${Protocol}://${Server}:${Port}${href}"
          $result = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
          while ($result.state -ne "finished"){
            $result = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
          }                           
        }
        # Build and attach distributor config
        $uri = "${Protocol}://${Server}:${Port}" + 
               "/pulp/api/v2/repositories/${idItem}/distributors/"
        foreach ($distributor in $repoItem.distributors) {
          $body = $distributor |
                  Select-Object distributor_type_id,
                                @{Name="distributor_id"; Expression = {$_.id}},
                                auto_publish,
                                @{Name='distributor_config';
                                  Expression={$_.config}} |
                  ConvertTo-Json
          $result = Invoke-RestMethod -Uri $uri -Method Post `
                                     -Certificate $cert -body $body
        }

        Get-PulpRpmRepo -Server $Server -Port $Port `
                        -Protocol $Protocol -Id $repoItem.id
      }                                                         
    } #end If
    Else { # String,int,bool type parameters
      If ($displayNameFromId){
        $DisplayName = $Id
      }
      If ($relativeUrlFromFeed){
        $RelativeUrl = "/" +
                      ($feed.split("/")[3..($feed.split("/").length)] -join "/")
      }
      elseif ($relativeUrlFromId){
        $RelativeUrl = $Id
      }
      
      $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol      
      
      # Create basic repo
      $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/repositories/"
      $body = "{ `"id`": `"$Id`""
      if ($DisplayName) {$body += ", `"display_name`": `"$DisplayName`""}
      if ($Description) {$body += ", `"description`": `"$Description`""}
  
      # Add repo notes
      $body += ", `"notes`": {`"_repo-type`": `"rpm-repo`""
      if ($Note){
        foreach ($noteItem in ($Note -replace '\s').split(",")){
          $noteName =  $noteItem.split("=")[0]
          $noteValue = $noteItem.split("=")[1]
          $body += ", `"$noteName`": `"$noteValue`""
        }
      }
      $body += "}}"
      $result = Invoke-RestMethod -Uri $uri -Method Post `
                                  -Certificate $cert -body $body
  
      # Build and attach importer config
      $uri = "${Protocol}://${Server}:${Port}" + 
            "/pulp/api/v2/repositories/${Id}/importers/"
      $config = "{"
  
      # Importer strings
      if ($Feed) {$config += "`"feed`": `"$Feed`", "}
      if ($FeedCaCert) {$config += "`"ssl_ca_cert`": `"$FeedCaCert`", "}
      if ($FeedCert) {$config += "`"ssl_client_cert`": `"$FeedCert`", "}
      if ($FeedKey) {$config += "`"ssl_client_key`": `"$FeedKey`", "}
      if ($ProxyHost) {$config += "`"proxy_host`": `"$ProxyHost`", "}
      if ($ProxyPort) {$config += "`"proxy_port`": `"$ProxyPort`", "}
      if ($ProxyUser) {$config += "`"proxy_username`": `"$ProxyUser`", "}
      if ($ProxyPass) {$config += "`"proxy_password`": `"$ProxyPass`", "}
      if ($BasicauthUser) {
        $config += "`"basic_auth_username`": `"$BasicauthUser`", "}
      if ($BasicauthPass) {
        $config += "`"basic_auth_password`": `"$BasicauthPass`", "}
  
      # Importer ints
      if ($MaxDownloads) {$config += "`"max_downloads`": ${MaxDownloads}, "}
      if ($MaxSpeed) {$config += "`"max_speed`": $MaxSpeed"}
      if ($RetainOldCount) {
        $config += "`"retain_old_count`": ${RetainOldCount}, "
      }
  
      # Importer bools
      if ($Validate -eq $true -or $Validate -eq $false) {
        $validateStr = ([string]$Validate).ToLower()
        $config += "`"validate`": ${validateStr}, "
      }
      if ($VerifyFeedSsl -eq $true -or $VerifyFeedSsl -eq $false){
        $verifyFeedSslStr = ([string]$VerifyFeedSsl).ToLower()
        $config += "`"ssl_validation`": ${verifyFeedSslStr}, "
      }
      if ($RemoveMissing -eq $true -or $RemoveMissing -eq $false){
        $removeMissingStr = ([string]$RemoveMissing).ToLower()
        $config += "`"remove_missing`": ${removeMissingStr}, "
      }
  
      # Importer objects
      if ($Skip) {
        $config += "`"type_skip_list`": ["
        foreach ($item in ($Skip -replace '\s').split(',')) {
          $config += "`"$item`", "
        }
        $config = $config.Trim(","," ") + "], "
      }
  
      $config = $config.Trim(","," ") + "}"
      $body = "{ `"importer_type_id`": `"yum_importer`""
      if ($config -ne '{}') {
        $body += ", `"importer_config`": $config"
      }
      $body += "}"
      $result = Invoke-RestMethod -Uri $uri -Method Post `
                                  -Certificate $cert -body $body
  
      # Wait for attach to complete
      $href = $result.spawned_tasks._href
      $uri = "${Protocol}://${Server}:${Port}${href}"
      $result = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
      while ($result.state -ne "finished"){
        $result = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
      }
  
      # Build and attach distributor config
      $uri = "${Protocol}://${Server}:${Port}" + 
            "/pulp/api/v2/repositories/${Id}/distributors/"
      $config = "{"
  
      # Distributor strings
      $config += "`"relative_url`": `"$RelativeUrl`", "
      if ($ChecksumType) {$config += "`"checksum_type`": `"$ChecksumType`", "}
      if ($GpgKey) {$config += "`"gpgkey`": `"$GpgKey`", "}
      if ($HostCa) {$config += "`"https_ca`": `"$HostCa`", "}
      if ($AuthCa) {$config += "`"auth_ca`": `"$AuthCa`", "}
      if ($AuthCert) {$config += "`"auth_cert`": `"$AuthCert`", "}
  
      # Distributor bools
      $serveHttpStr = ([string]$ServeHttp).ToLower()
      $config += "`"http`": $serveHttpStr, "
      $serveHttpsStr = ([string]$ServeHttps).ToLower()
      $config += "`"https`": $serveHttpsStr, "
  
      If ($PSBoundParameters.ContainsKey('GenerateSqlite')) {
        $generateSqliteStr = ([string]$GenerateSqlite).ToLower()
        $config += "`"generate_sqlite`": $generateSqliteStr, "
      }
  
      $config = $config.Trim(","," ") + "}"
      $autoPublishStr = ([string]$AutoPublish).ToLower()
      $body = "{ `"distributor_type_id`": `"yum_distributor`"," +
        " `"distributor_id`": `"yum_distributor`"," + 
        " `"distributor_config`": ${config}, `"auto_publish`": $autoPublishStr}"
      # yum_distributor
      $result = Invoke-RestMethod -Uri $uri -Method Post `
                                  -Certificate $cert -body $body
      $config = "{`"http`": $serveHttpStr, `"https`": ${serveHttpsStr}}"
      $body = "{ `"distributor_type_id`": `"export_distributor`"," +
        " `"distributor_id`": `"export_distributor`"," + 
        " `"distributor_config`": ${config}, `"auto_publish`": $autoPublishStr}"
      # export_distributor
      $result = Invoke-RestMethod -Uri $uri -Method Post `
                                  -Certificate $cert -body $body
  
      Return (Get-PulpRpmRepo -Server $Server -Port $Port `
                              -Protocol $Protocol -Id $Id)

    } #end Else
  } #end Process
} #end Function New-PulpRpmRepo

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpRpmRepo
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
      If ($Repo) { # Object-based parameter
        $Id = $Repo | Select-Object -ExpandProperty id
      }
      $repos = Get-PulpRpmRepo -Server $server -Port $Port `
                              -Protocol $Protocol -Id $Id
      foreach ($repo in $repos) {
        $deleteId = $repo.id
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/repositories/${deleteId}/"
        Invoke-RestMethod -Uri $uri -Method Delete -Certificate $cert
      }
  } #end Process
} #end function Remove-PulpRpmRepo

Function Publish-PulpRepo
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id,
    [Parameter(Mandatory=$true)] [string] $Type) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
      If ($Repo) { # Object-based parameter
        $Id = $Repo | Select-Object -ExpandProperty id
      }
      $repos = Get-PulpRepo -Server $server -Port $Port `
                              -Protocol $Protocol -Id $Id -Type $Type
      foreach ($repo in $repos) {
        if ($Type -eq 'rpm'){ $dist = 'yum' }
        else { $dist = $Type.ToLower() }
        $publishId = $repo.id
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/repositories/${publishId}/actions//publish/"
        $body = '{"override_config": null, "id": "' + $dist +'_distributor"}'
        Invoke-RestMethod -Uri $uri -Method Post -Certificate $cert -Body $body
      }
  } #end Process
} #end function Publish-PulpRepo

# .ExternalHelp powershell-pulp-help.xml
Function Publish-PulpRpmRepo
{
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                           [string]     ${Server},
                                           [int]        ${Port},
                                           [string]     ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]   [psobject[]] ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]   [string[]]   ${Id})
  Begin {
    Try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)){
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd =
          $ExecutionContext.InvokeCommand.GetCommand('Publish-PulpRepo',
          [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'rpm' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      Throw
    }
  }
  Process {
    Try {
        $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Publish-PulpRpmRepo

# .ExternalHelp powershell-pulp-help.xml
Function Publish-PulpIsoRepo {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                           [string]     ${Server},
                                           [int]        ${Port},
                                           [string]     ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]   [psobject[]] ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]   [string[]]   ${Id})
  Begin {
    Try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)){
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd =
          $ExecutionContext.InvokeCommand.GetCommand('Publish-PulpRepo',
          [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'iso' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      Throw
    }
  }
  Process {
    Try {
        $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Publish-PulpIsoRepo

# .ExternalHelp powershell-pulp-help.xml
Function Publish-PulpPuppetRepo {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                           [string]     ${Server},
                                           [int]        ${Port},
                                           [string]     ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]   [psobject[]] ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]   [string[]]   ${Id})
  Begin {
    Try {
      $outBuffer = $null
      if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)){
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd =
          $ExecutionContext.InvokeCommand.GetCommand('Publish-PulpRepo',
          [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'puppet' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      Throw
    }
  }
  Process {
    Try {
        $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Publish-PulpPuppetRepo

# .ExternalHelp powershell-pulp-help.xml
Function Start-PulpRpmRepoSync
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id = '*') #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
      If ($Repo) { # Object-based parameter
        $Id = $Repo | Select-Object -ExpandProperty id
      }
      $repos = Get-PulpRpmRepo -Server $server -Port $Port `
                              -Protocol $Protocol -Id $Id
      foreach ($repo in $repos) {
        $syncId = $repo.id
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/repositories/${syncId}/actions/sync/"
        $result = Invoke-RestMethod -Uri $uri -Method Post -Certificate $cert
      }
      return $repos
  } #end Process
} #end function Start-PulpRpmRepoSync

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpRpmRepoSyncStatus
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id = '*') #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
      If ($Repo) { # Object-based parameter
        $Id = $Repo | Select-Object -ExpandProperty id
      }
      $repos = Get-PulpRpmRepo -Server $server -Port $Port `
                              -Protocol $Protocol -Id $Id
      foreach ($repo in $repos) {
        $syncId = $repo.id
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/tasks/search/"
        $body = '{"criteria": {"filters": {"state": {"$nin": ' + 
                '["finished", "error", "canceled", "skipped"]}, "tags": ' +
                '{"$all": ["pulp:repository:'+ $syncId +
                '", "pulp:action:sync"]}}}}'
        $result = Invoke-RestMethod -Uri $uri -Method Post -Certificate $cert -Body $body
        Get-PulpTask $result
      }
  } #end Process
} #end function Get-PulpRpmRepoSyncStatus

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpRpmRepoSyncSchedule
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id       = "*") #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    If ($Repo) { # Object-based parameter
      $Id = $Repo | Select-Object -ExpandProperty id
    }
    $repos = Get-PulpRpmRepo -Server $server -Port $Port `
                             -Protocol $Protocol -Id $Id
    foreach ($repoItem in $repos){
      $repoId = $repoItem.id
      $importers = $repoItem | Select-Object -ExpandProperty importers |
                  Where-Object {($_.importer_type_id -eq 'yum_importer')}
      foreach ($importer in $importers){
        $importerId = $importer.id
        $uri = "${Protocol}://${Server}:${Port}" + 
               "/pulp/api/v2/repositories/${repoId}" +
               "/importers/${importerId}/schedules/sync/"
        Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
      }
    }
  } #end Process
} #end function Get-PulpRpmRepoSyncSchedule

# .ExternalHelp powershell-pulp-help.xml
Function New-PulpRpmRepoSyncSchedule
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Object")]  [PSCustomObject[]]  $Repo,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]  $Id,
    [Parameter(Mandatory=$true)]            [string]    $Schedule,
    [Parameter(Mandatory=$false)]           [int]       $FailureThreshold
  ) #end Param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol    
  } #end Begin
  Process {
    If ($Repo) { # Object-based parameter
      $Id = $Repo | Select-Object -ExpandProperty id
    }
    $repos = Get-PulpRpmRepo -Server $server -Port $Port `
                             -Protocol $Protocol -Id $Id
    foreach ($repoItem in $repos){
      $repoId = $repoItem.id
      $importers = $repoItem | Select-Object -ExpandProperty importers |
                  Where-Object {($_.importer_type_id -eq 'yum_importer')}
      foreach ($importer in $importers){
        $importerId = $importer.id
        $uri = "${Protocol}://${Server}:${Port}" + 
               "/pulp/api/v2/repositories/${repoId}" +
               "/importers/${importerId}/schedules/sync/"
        $body = "{ `"schedule`": `"$Schedule`""
        if ($FailureThreshold){
          $body += ", `"failure_threshold`": $FailureThreshold"
        }
        $body += '}'
        Invoke-RestMethod -Uri $uri -Method Post -Certificate $cert -body $body
      }
    }
    Get-PulpRpmRepoSyncSchedule -Server $server -Port $Port `
                                -Protocol $Protocol -Id $Id
  } #end Process
} #end Function New-PulpRpmRepoSyncSchedule

Function Add-PulpContentUnit {
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)]
    [string]$Server = (Get-PulpLocalConfig -Server).Server,
    
    [Parameter(Mandatory=$false)]
    [int]$Port = (Get-PulpLocalConfig -Port).Port,
    
    [Parameter(Mandatory=$false)]
    [string]$Protocol = (Get-PulpLocalConfig -Protocol).Protocol,
    
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName="ObjectsPath")]
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName="ObjectsUrl")]
    [PSCustomObject[]]$Repo,
    
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName="StringsPath")]
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName="StringsUrl")]
    [string[]]$Id,
    
    [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false, ParameterSetName="ObjectsPath")]
    [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false, ParameterSetName="StringsPath")]
    [string[]]$Path,
    
    [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false, ParameterSetName="ObjectsUrl")]
    [Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$false, ParameterSetName="StringsUrl")]
    [string]$Url,
    
    [Parameter(Mandatory=$false)]
    [switch]$NoPublish,
    
    [Parameter(Mandatory=$true)]
    [string]$Type
  ) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    If ($Type -eq 'puppet'){ $unitType = 'puppet_module' }
    Else { $unitType = $Type }
    # Do downloads
    If ($Url) {
       $null = New-Item -Type Directory -Force "$ENV:TMP\powershell-pulp"
       $DownloadPath = "$ENV:TMP\powershell-pulp\" + (Split-Path -Path $Url -Leaf)
       Invoke-WebRequest -Uri $Url -OutFile $DownloadPath
    }
    # Upload each file and record uploadId, fileName, fileSize in array of
    # hashes for later use
    $uploadHashes = @()
    if ($DownloadPath) {
      $files = Get-ChildItem $DownloadPath
    } else {
      $files = Get-ChildItem $Path
    }
    foreach ($file in $files) {
      # Get upload id
      $uri = "${Protocol}://${Server}:${Port}" +
           "/pulp/api/v2/content/uploads/"
      #write-host "DEBUG: Getting upload ID at URL: ${url}"
      $response = Invoke-RestMethod -Uri $uri -Method Post `
        -Certificate $cert
      $uploadId = $response.upload_id
      $uploadRef = $response._href
      #write-host "DEBUG: Got uploadId ${uploadId}"
      #write-host "DEBUG: Got uploadRef ${uploadRef}"
      # Upload file (in chunks if bigger than 1MB)
      $fileName = [string]$file
      $shortFileName = Split-Path $fileName -leaf -resolve
      $chunkSize=1048576
      $fileSize = (get-item $fileName).length
      $uploadHashes += ,@{'uploadId' = $uploadId; 'fileName' = $fileName;
        'shortFileName' = $shortFileName; 'fileSize' = $fileSize}
      # If big file, upload in chunks appending offset to URL
      if ($fileSize -gt $chunksize) {
        $uri = "${Protocol}://${Server}:${Port}" + $uploadRef #+ "0/"
        
        $fileStream = [System.IO.File]::OpenRead($file)
        $chunk = New-Object byte[] $chunkSize
        $offset = 0
        while( $bytesRead = $fileStream.Read($chunk,0,$chunkSize) ){
          $thisUpload = New-Object byte[] $bytesRead
          $thisUpload = [byte[]]($chunk[0..($bytesRead - 1)])
          $progressPreference = 'silentlyContinue'
          #write-host "DEBUG: Invoke-RestMethod -Uri \"${uri}${offset}/\" -ContentType \"application/data\" -Body $thisUpload -Method Put -Certificate [cert]"
          $response = Invoke-RestMethod -Uri "${uri}${offset}/" `
            -ContentType "application/data" -Body $thisUpload -Method Put `
            -Certificate $cert
          $progressPreference = 'Continue'
          $offset += $chunkSize
          if (($offset / $fileSize*100) -le 100){
            $percentComplete = ($offset / $fileSize*100)
          }
          else {
            $percentComplete = 100
          }
          Write-Progress -Activity `
            "Uploading ${shortFileName} to ${Server}" `
            -status "Uploaded $offset bytes" `
            -percentComplete $percentComplete
        }
        $fileStream.Close()
      # If small file upload the whole thing in one go
      } else {
        $uri = "${Protocol}://${Server}:${Port}" + $uploadRef + "0/"
        #write-host "DEBUG: Invoke-RestMethod -Uri $uri -InFile $fileName -Method Put -Certificate [cert]"
        $response = Invoke-RestMethod -Uri $uri `
            -InFile $fileName -Method Put -Certificate $cert
      }
    }
    $pipelineCount = 0
    $firstRepoId = ''
  }
  Process {
    If ($Repo) { # Object-based parameter
      $Id = $Repo | Select-Object -ExpandProperty id
    }
    elseif ($_) {
    #else {
      $Id = $_
    }
      
    $repos = Get-PulpRepo -Server $server -Port $Port `
                             -Protocol $Protocol -Id $Id -Type $Type
    # Import/copy each file into each repo using uploadhashes recorded earlier
    $repocount = 0
    foreach ($repoObject in $repos) {
      $addId = $repoObject.id
      foreach ($uploadHash in $uploadHashes) {
        $uploadId = $uploadHash.uploadId
        $fileName = $uploadHash.fileName
        $shortFileName = $uploadHash.shortFileName
        $fileSize = $uploadHash.fileSize
        # If this is the first repo we import using upload ID...
        if (($repocount -eq 0) -and ($pipelineCount -eq 0)) {
          $firstRepoId = $addId
          # Metadata for RPM upload
          if ($unitType -eq 'rpm') {
            $unitKey = '{}'
            $unitMetaData = '{}'
          }
          # Metadata for Puppet module upload
          elseif ($unitType -eq 'puppet_module') {
            $unitKey = '{}'
            $unitMetaData = '{}'
          }
          # Metadata for other uploads (inc ISO)
          else {
            $checksum = ((Get-FileHash -Path $fileName `
                          -Algorithm SHA256).Hash).ToLower()
            $unitKey =  '{"checksum": "' + $checksum + '", "name": "' +
                          $shortFileName + '", "size": ' + $fileSize + '}'
            $unitMetaData = '{}'
          }
          $uri = "${Protocol}://${Server}:${Port}" +
            "/pulp/api/v2/repositories/${addId}/actions/import_upload/"
          $body = '{"override_config": {}, "unit_type_id": "' + $unitType +'", ' + 
                  '"upload_id": "' + $uploadId + '", "unit_key": ' + $unitKey +
                  ', "unit_metadata": '+ $unitMetadata  +'}'
          #write-host "DEBUG: Invoke-RestMethod -Uri $uri -Body $body -Method Post -Certificate [cert]"
          Invoke-RestMethod -Uri $uri -Body $body -Method Post `
                            -Certificate $cert
          Start-Sleep -s 5
        }
        # ...otherwise we copy from the first repo
        else {
          # Horrible hack to get puppet module name from file name
          If ($unitType -eq 'puppet_module') {
            $shortFileName = ($shortFileName -Split '-')[1]
          }
          Copy-PulpContentUnit -Id $addId -Source $firstRepoId `
                               -Name $shortFileName -NoPublish -Type $Type
        }
      }
      # Publish changes
      If (!$NoPublish) {
        Publish-PulpRepo -Id $addId -Type $Type
      }
      $repocount += 1
    }
    $pipelineCount += 1
  } #end Process
  End {
    # Delete downloaded file
    If ($DownloadPath) {
      Remove-Item -Recurse -Force $DownloadPath
    }
  } # end End
} #end function Add-PulpContentUnit

# .ExternalHelp powershell-pulp-help.xml
Function Add-PulpRpm {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                            [string]     ${Server},
                                            [int]        ${Port},
                                            [string]     ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [psobject[]] ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [string[]]   ${Id},
    [Parameter(Mandatory=$true,
               Position=1)]                 [string[]]   ${Path},
                                            [switch]     ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Add-PulpContentUnit', [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'rpm' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    } Catch { Throw }
  }
  Process {
    Try { $steppablePipeline.Process($_) }
    Catch { Throw }
  }
  End {
    Try { $steppablePipeline.End() }
    Catch { Throw }
  }
} #end function Add-PulpRpm

# .ExternalHelp powershell-pulp-help.xml
Function Add-PulpIso {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                            [string]     ${Server},
                                            [int]        ${Port},
                                            [string]     ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [psobject[]] ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [string[]]   ${Id},
    [Parameter(Mandatory=$true,
               Position=1)]                 [string[]]   ${Path},
                                            [switch]     ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Add-PulpContentUnit', [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'iso' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    } Catch { Throw }
  }
  Process {
    Try { $steppablePipeline.Process($_) }
    Catch { Throw }
  }
  End {
    Try { $steppablePipeline.End() }
    Catch { Throw }
  }
} #end function Add-PulpIso

# .ExternalHelp powershell-pulp-help.xml
Function Add-PulpPuppetModule {
  [CmdletBinding(DefaultParameterSetName='Repo ID and module path')]
  Param(
    [string]${Server},
    [int]${Port},
    [string]${Protocol},
    
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName='Repo object and module path')]
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName='Repo object and module name, author, version')]
    [psobject[]]${Repo},
    
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName='Repo ID and module path')]
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ParameterSetName='Repo ID and module name, author, version')]
    [string[]]${Id},
    
    [Parameter(Mandatory=$true, Position=1, ParameterSetName='Repo object and module path')]
    [Parameter(Mandatory=$true, Position=1, ParameterSetName='Repo ID and module path')]
    [string[]]${Path},
    
    [Parameter(Mandatory=$false, ParameterSetName='Repo object and module name, author, version')]
    [Parameter(Mandatory=$false, ParameterSetName='Repo ID and module name, author, version')]
    [string]${ForgeBaseUrl} = 'https://forge.puppet.com/v3/files/',
    
    [Parameter(Mandatory=$true, Position=1, ParameterSetName='Repo object and module name, author, version')]
    [Parameter(Mandatory=$true, Position=1, ParameterSetName='Repo ID and module name, author, version')]
    [string]${Author},

    [Parameter(Mandatory=$true, Position=2, ParameterSetName='Repo object and module name, author, version')]
    [Parameter(Mandatory=$true, Position=2, ParameterSetName='Repo ID and module name, author, version')]
    [string]${Name},
    
    [Parameter(Mandatory=$true, Position=3, ParameterSetName='Repo object and module name, author, version')]
    [Parameter(Mandatory=$true, Position=3, ParameterSetName='Repo ID and module name, author, version')]
    [string]${Version}, 
    
    [switch]${NoPublish})
  Begin {
    If ($Author) {
      $Url = "${ForgeBaseUrl}${Author}-${Name}-${Version}.tar.gz"
      $null = $PSBoundParameters.Remove('ForgeBaseUrl')
      $null = $PSBoundParameters.Remove('Author')
      $null = $PSBoundParameters.Remove('Name')
      $null = $PSBoundParameters.Remove('Version')
    }
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Add-PulpContentUnit', [System.Management.Automation.CommandTypes]::Function)
      If ($Url) {
        # write-host "DEBUG: Got url ${url}"
        $scriptCmd = {& $wrappedCmd @PSBoundParameters -Url $Url -Type 'puppet' }
      } else {
        $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'puppet' }
      }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    } Catch { Throw }
  }
  Process {
    Try { $steppablePipeline.Process($_) }
    Catch { Throw }
  }
  End {
    Try { $steppablePipeline.End() }
    Catch { Throw }
  }
} #end function Add-PulpPuppetModule

Function Get-PulpContentUnit
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id,
    [Parameter(Mandatory=$false,
               Position=1,
               ValueFromPipeline=$false)] [string]$Name = '*',
    [Parameter(Mandatory=$true)]          [string] $Type) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    If ($Repo) { # Object-based parameter
      $Id = $Repo | Select-Object -ExpandProperty id
    }
    $repos = Get-PulpRepo -Server $server -Port $Port `
                            -Protocol $Protocol -Id $Id -Type $Type
    foreach ($repo in $repos) {
      If ($Type -eq 'puppet') {
        $Type = 'puppet_module'
      }
      $repoId = $repo.id
      $uri = "${Protocol}://${Server}:${Port}" +
              "/pulp/api/v2/repositories/${repoId}/search/units/"
      $body = '{"criteria": {"type_ids": ["' + $Type + 
              '"], "filters": {"unit": {}}}}'
      $units = Invoke-RestMethod -Uri $uri -Method Post -Body $body `
                                 -Certificate $cert
      If ($Type -eq 'rpm'){
        $units | Where-Object {($_.metadata.filename -like $Name) -and
                              ($_.unit_type_id -eq $Type)}
      }
      ElseIf ($Type -eq 'puppet_module'){
        
        $modAuthor = $Name.split("-")[0]
        $modName = if ($Name.split("-")[1] -ne $null) {
          $Name.split("-")[1]
        } else {
          '*'
        }
        $modVersion = if ($Name.split("-")[2] -ne $null) {
          $Name.split("-")[2]
        } else {
          '*'
        }
        $units | Where-Object {($_.metadata.author -like $modAuthor) -and
                               ($_.metadata.name -like $modName) -and
                               ($_.metadata.version -like $modVersion) -and
                               ($_.unit_type_id -eq $Type)}
      }
      Else {
        $units | Where-Object {($_.metadata.name -like $Name) -and
                              ($_.unit_type_id -eq $Type)}
      }
    } #end foreach ($repo in $repos)
  } #end Process
} #end function Get-PulpContentUnit

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpRpm {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                            [string]      ${Server},
                                            [int]         ${Port},
                                            [string]      ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [psobject[]]  ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [string[]]    ${Id},
    [Parameter(Position=1)]                 [string]      ${Name})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Get-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'rpm' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      Throw
    }
  }
  Process {
    Try {
      $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Get-PulpRpm

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpIso {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                            [string]      ${Server},
                                            [int]         ${Port},
                                            [string]      ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [psobject[]]  ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [string[]]    ${Id},
    [Parameter(Position=1)]                 [string]      ${Name})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Get-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'iso' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      Throw
    }
  }
  Process {
    Try {
      $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Get-PulpIso

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpPuppetModule {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                            [string]      ${Server},
                                            [int]         ${Port},
                                            [string]      ${Protocol},
    [Parameter(ParameterSetName='Objects',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [psobject[]]  ${Repo},
    [Parameter(ParameterSetName='Strings',
               Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)]    [string[]]    ${Id},
    [Parameter(Position=1)]                 [string]      ${Name})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Get-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'puppet' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      Throw
    }
  }
  Process {
    Try {
      $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Get-PulpPuppetModule

Function Copy-PulpContentUnit {
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Repo,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$Id,
    [Parameter(Mandatory=$false,
               Position=1,
               ValueFromPipeline=$false)] [string]$Name = '.+',
    [Parameter(Mandatory=$true,
               Position=1,
               ValueFromPipeline=$false)] [string]$Source,
    [Parameter(Mandatory=$false)]         [switch]$NoPublish,
    [Parameter(Mandatory=$true)]          [string] $Type) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    If ($Type -eq 'puppet'){ $unitType = 'puppet_module' }
    Else { $unitType = $Type }
  }
  Process {
      If ($Repo) { # Object-based parameter
        $Id = $Repo | Select-Object -ExpandProperty id
      }
      $repos = Get-PulpRepo -Server $server -Port $Port `
                              -Protocol $Protocol -Id $Id -Type $Type
      foreach ($repo in $repos) {
        $repoId = $repo.id
          $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/repositories/${repoId}/actions/associate/"
          If ($unitType -eq 'rpm'){
            $body = '{"source_repo_id": "' + $Source +
                  '", "override_config": {}, "criteria": {"fields": {"unit": ' +
                  '["name", "epoch", "version", "release", "arch", ' +
                  '"checksum", "checksumtype"]}, "type_ids": ["rpm"], ' +
                  '"filters": {"unit": {"filename": {"$regex":' +
                  ' "' + $Name + '"}}}}}'
          } else {
            $body = '{"source_repo_id": "' + $Source +
               '", "override_config": {}, "criteria": {"type_ids": ["' +
               $unitType + '"], ' +
               '"filters": {"unit": {"name": {"$regex":' +
               ' "' + $Name + '"}}}}}'
          }
          Invoke-RestMethod -Uri $uri -Method Post -Body $body `
                            -Certificate $cert
          If (!$NoPublish){
            Publish-PulpRepo -Id $RepoId -Type $Type
          }
     }
  } #end Process
} #end function Copy-PulpContentUnit

# .ExternalHelp powershell-pulp-help.xml
Function Copy-PulpRpm {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                                [string]      ${Server},
                                                [int]         ${Port},
                                                [string]      ${Protocol},
      [Parameter(ParameterSetName='Objects',
                 Mandatory=$true,
                 Position=0,
                 ValueFromPipeline=$true)]      [psobject[]]  ${Repo},
      [Parameter(ParameterSetName='Strings',
                 Mandatory=$true, Position=0,
                 ValueFromPipeline=$true)]      [string[]]    ${Id},
      [Parameter(Position=1)]                   [string]      ${Name},
      [Parameter(Mandatory=$true, Position=1)]  [string]      ${Source},
                                                [switch]      ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Copy-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'rpm' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      throw
    }
  }
  Process {
    Try {
      $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Copy-PulpRpm

# .ExternalHelp powershell-pulp-help.xml
Function Copy-PulpIso {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                                [string]      ${Server},
                                                [int]         ${Port},
                                                [string]      ${Protocol},
      [Parameter(ParameterSetName='Objects',
                 Mandatory=$true,
                 Position=0,
                 ValueFromPipeline=$true)]      [psobject[]]  ${Repo},
      [Parameter(ParameterSetName='Strings',
                 Mandatory=$true, Position=0,
                 ValueFromPipeline=$true)]      [string[]]    ${Id},
      [Parameter(Position=1)]                   [string]      ${Name},
      [Parameter(Mandatory=$true, Position=1)]  [string]      ${Source},
                                                [switch]      ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Copy-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'iso' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      throw
    }
  }
  Process {
    Try {
      $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Copy-PulpIso

# .ExternalHelp powershell-pulp-help.xml
Function Copy-PulpPuppetModule {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                                [string]      ${Server},
                                                [int]         ${Port},
                                                [string]      ${Protocol},
      [Parameter(ParameterSetName='Objects',
                 Mandatory=$true,
                 Position=0,
                 ValueFromPipeline=$true)]      [psobject[]]  ${Repo},
      [Parameter(ParameterSetName='Strings',
                 Mandatory=$true, Position=0,
                 ValueFromPipeline=$true)]      [string[]]    ${Id},
      [Parameter(Position=1)]                   [string]      ${Name},
      [Parameter(Mandatory=$true, Position=1)]  [string]      ${Source},
                                                [switch]      ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Copy-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'puppet' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch {
      throw
    }
  }
  Process {
    Try {
      $steppablePipeline.Process($_)
    }
    Catch {
      Throw
    }
  }
  End {
    Try {
      $steppablePipeline.End()
    }
    Catch {
      Throw
    }
  }
} #end function Copy-PulpPuppetModule

Function Remove-PulpContentUnit {
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [PSCustomObject[]]$ContentUnit,
    [Parameter(Mandatory=$false)]         [switch]$NoPublish,
    [Parameter(Mandatory=$true)]          [string] $Type) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    $repos = @()
    If ($Type -eq 'puppet'){ $unitType = 'puppet_module' }
    Else { $unitType = $Type }
  }
  Process {
        $repoId = $ContentUnit | Select-Object -ExpandProperty repo_id
        $repos += $repoID
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/repositories/${repoId}/actions/unassociate/"
        If ($unitType -eq 'rpm') {
          $fileName = $ContentUnit | Select-Object -ExpandProperty metadata | 
            Select-Object -ExpandProperty filename
          $body = '{"criteria": {"fields": {"unit": ["name", "epoch", ' +
                '"version", "release", "arch", "checksum", "checksumtype"]},' +
                ' "type_ids": ["rpm"], "filters": {"unit": {"filename": "' +
                $fileName + '"}}}}'
        }
        else {
          $id = $ContentUnit | Select-Object -ExpandProperty metadata | 
            Select-Object -ExpandProperty _id
          $body = '{"criteria": {"type_ids": ["' + $unitType + '"], "filters": ' +
                  '{"unit": {"_id": "' + $id + '"}}}}'
        }
        Invoke-RestMethod -Uri $uri -Method Post -Body $body -Certificate $cert
  }
  End {
    If (!$NoPublish) {
      $repos | Select-object -Unique | Get-PulpRepo -Type $Type |
               Publish-PulpRepo -Type $Type
    }
  }
} #end function Remove-PulpContentUnit

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpRpm {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                          [string]    ${Server},
                                          [int]       ${Port},
                                          [string]    ${Protocol},
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [psobject[]] ${ContentUnit},
                                         [switch]     ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Remove-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'rpm' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch { Throw }
  }
  Process {
    Try { $steppablePipeline.Process($_) }
    Catch { Throw }
  }
  End {
    Try { $steppablePipeline.End() }
    Catch { Throw }
  }
} #end function Remove-PulpRpm

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpIso {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                          [string]    ${Server},
                                          [int]       ${Port},
                                          [string]    ${Protocol},
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [psobject[]] ${ContentUnit},
                                         [switch]     ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Remove-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'iso' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch { Throw }
  }
  Process {
    Try { $steppablePipeline.Process($_) }
    Catch { Throw }
  }
  End {
    Try { $steppablePipeline.End() }
    Catch { Throw }
  }
} #end function Remove-PulpIso

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpPuppetModule {
  [CmdletBinding(DefaultParameterSetName='Strings')]
  Param(
                                          [string]    ${Server},
                                          [int]       ${Port},
                                          [string]    ${Protocol},
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [psobject[]] ${ContentUnit},
                                         [switch]     ${NoPublish})
  Begin {
    Try {
      $outBuffer = $null
      If ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
        $PSBoundParameters['OutBuffer'] = 1
      }
      $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand(
        'Remove-PulpContentUnit',
        [System.Management.Automation.CommandTypes]::Function)
      $scriptCmd = {& $wrappedCmd @PSBoundParameters -Type 'puppet' }
      $steppablePipeline = $scriptCmd.GetSteppablePipeline()
      $steppablePipeline.Begin($PSCmdlet)
    }
    Catch { Throw }
  }
  Process {
    Try { $steppablePipeline.Process($_) }
    Catch { Throw }
  }
  End {
    Try { $steppablePipeline.End() }
    Catch { Throw }
  }
} #end function Remove-PulpPuppetModule

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpTask
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Task,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]$TaskId,
    [Parameter(Mandatory=$false)]           [switch]$NoSpawnedTasks,
    [Parameter(Mandatory=$false)]           [switch]$All) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    
    if (!$Task -and !$TaskID){
      $uri = "${Protocol}://${Server}:${Port}" +
             "/pulp/api/v2/tasks/search/"
      if ($All) {
        $body = '{"criteria": {"fields": ["tags", "task_id", "state", ' +
                '"start_time", "finish_time"]}}'

      } else {
        $body = '{"criteria": {"fields": ["tags", "task_id", "state", ' +
                '"start_time", "finish_time"], "filters": {"state": ' +
                '{"$in": ["running", "waiting"]}}}}'
      }
      $taskList = Invoke-RestMethod -Uri $uri -Method Post -Certificate $cert `
                               -Body $body
    }
  }
  Process {
      if ($TaskID) { # Strings
        $uri = "${Protocol}://${Server}:${Port}" +
                  "/pulp/api/v2/tasks/${TaskID}/"
        $result = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
        Get-PulpTask $result
      } 
      elseif ($Task) { # Objects
        if ($Task.task_id -ne $null) {
          $TaskIds = $Task | Select-Object -ExpandProperty task_id
        }
        foreach ($item in $TaskIDs) {
          $uri = "${Protocol}://${Server}:${Port}" +
                  "/pulp/api/v2/tasks/${item}/"
          Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
        }
        if (($Task.spawned_tasks -ne $null) -and !$NoSpawnedTasks){
          $spawnedTasks = Get-PulpTask ($Task | Select-Object -ExpandProperty spawned_tasks)
          Get-PulpTask $spawnedTasks
        }          
      }
      else { # List
        $taskList
      }
  } #end Process
} #end function Get-PulpTask

# .ExternalHelp powershell-pulp-help.xml
Function Stop-PulpTask
{
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)] [string] $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)] [int]    $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)] [string] $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [PSCustomObject[]]$Task) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    $taskID = $Task | Select-Object -ExpandProperty task_id
    foreach ($item in $taskID) {
      $uri = "${Protocol}://${Server}:${Port}" +
             "/pulp/api/v2/tasks/${item}/"
      Invoke-RestMethod -Uri $uri -Method Delete -Certificate $cert
    }
  }
} #end function Stop-PulpTask

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpUser
{

  Param(
    [Parameter(Mandatory=$false)]            [string]$Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]            [int]   $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]            [string]$Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true)] [string[]]$Login    = @('*'),
    [Parameter(Mandatory=$false,Position=1)] [string]$Name     = '*') #end param

  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/users/"
    $users = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
  }
  Process {
    foreach ($item in $Login) {
      $users | Where-Object { ($_.login -like $item) -and ($_.name -like $Name) }
    }
  }
} #end function Get-PulpUser

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpRole
{

  Param(
    [Parameter(Mandatory=$false)]            [string]  $Server        = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]            [int]     $Port          =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]            [string]  $Protocol      = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$false,Position=0)] [string[]]$Id            = @('*'),
    [Parameter(Mandatory=$false,Position=1)] [string]  $DisplayName   = '*')
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/roles/"
    $roles = Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
  }
  Process {
    foreach ($item in $Id){
      $roles | Where-Object { ($_.id -like $item) -and
                              ($_.display_name -like $DisplayName) }
    }
  }
} #end function Get-PulpRole

# .ExternalHelp powershell-pulp-help.xml
Function Get-PulpPermission
{
 
 [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)]           [string]          $Server   = (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]           [int]             $Port     = (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]           [string]          $Protocol = (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Resource,
    [Parameter(Mandatory=$false,
               ParameterSetName="Objects")] [string]          $StripUriPrefix = '/pulp/api',
    [Parameter(Mandatory=$false,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")]  [String[]]       $Href) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    If ($Resource) {
     $Href = $Resource | Select-Object -ExpandProperty '_href'
     $Href = ($Href | ForEach-Object {$_ -replace "^${StripUriPrefix}",'' })
    }
    If ($Href) {
      foreach ($item in $Href) {
        $encodedHref = [System.Web.HttpUtility]::UrlEncode($href)
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/permissions/?resource=" + $encodedHref
        Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
      }
    }
    Else {
      $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/permissions/"
      Invoke-RestMethod -Uri $uri -Method Get -Certificate $cert
    }
  } #end Process
} #end function Get-PulpPermission

# .ExternalHelp powershell-pulp-help.xml
Function Set-PulpPermission
{
  [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)]           [string]          $Server   = (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]           [int]             $Port     = (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]           [string]          $Protocol = (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$Resource,
    [Parameter(Mandatory=$false,
               ParameterSetName="Objects")] [string]          $StripUriPrefix = '/pulp/api',
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [String[]]        $Href,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [PSCustomObject[]]$User,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [PSCustomObject[]]$Role,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [string[]]        $UserLogin,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [string[]]        $RoleId,
    [Parameter(Mandatory=$false)]           [switch]          $Grant,
    [Parameter(Mandatory=$false)]           [switch]          $Revoke,
    [Parameter(Mandatory=$false)]           [string]          $Permission,
    [Parameter(Mandatory=$false)]           [switch]          $Create,
    [Parameter(Mandatory=$false)]           [switch]          $Read,
    [Parameter(Mandatory=$false)]           [switch]          $Update,
    [Parameter(Mandatory=$false)]           [switch]          $Delete,
    [Parameter(Mandatory=$false)]           [switch]          $Execute,
    [Parameter(Mandatory=$false)]           [switch]          $All) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    If ( ($Grant -and $Revoke) -or (!$Grant -and !$Revoke) ) {
      Throw "Please specify one and only one of '-Grant' or '-Revoke'"
      Return
    }
    If ($Permission){
      If ($Permission -like "*CREATE*"){ $Create = $True }
      If ($Permission -like "*READ*"){ $Read = $True }
      If ($Permission -like "*UPDATE*"){ $Update = $True }
      If ($Permission -like "*DELETE*"){ $Delete = $True }
      If ($Permission -like "*EXECUTE*"){ $Execute = $True }
    }
    If ( (!$Create) -and (!$Read) -and (!$Update) -and (!$Delete) -and
         (!$Execute) -and (!$All) ) {
      Throw "Please specfiy at least one permission"
      Return
    }
    If ( (!$User) -and (!$Role) -and (!$UserLogin) -and (!$RoleId) ) {
      Throw  "Please specfiy at least one user or role"
      Return
    }

    If     ($Grant)  { $action = "grant_to" }
    elseif ($Revoke) { $action = "revoke_from" }

    $operations = @()
    If ($Create  -or $All)  { $operations += '"CREATE"'  }
    If ($Read    -or $All)  { $operations += '"READ"'    }
    If ($Update  -or $All)  { $operations += '"UPDATE"'  }
    If ($Delete  -or $All)  { $operations += '"DELETE"'  }
    If ($Execute -or $All)  { $operations += '"EXECUTE"' }
    $operations = $operations -join ", "

    $userLogins = @()
    $roleIds = @()
    If ($User) {
      $userLogins = $User | Select-Object -ExpandProperty 'login'
    }
    If ($UserLogin) {
      $userLogins += $UserLogin
    }
    If ($Role) {
      $RoleIds = $Role | Select-Object -ExpandProperty 'id'
    }
    If ($RoleId) {
      $roleIds += $RoleId
    }
  }
  Process {
    If ($Resource) {
     $Href = $Resource | Select-Object -ExpandProperty '_href'
     $Href = ($Href | ForEach-Object {$_ -replace "^${StripUriPrefix}",'' })
    }
    foreach ($hrefItem in $Href) {
      foreach ($userLoginItem in $userLogins) {
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/permissions/actions/" + $action + "_user/"
        $body = '{"operations": [' + $operations + '], "login": "' + $userLoginItem +
                '", "resource": "' + $hrefItem + '"}'
        $result = Invoke-RestMethod -Uri $uri -Body $body -Method Post `
                          -Certificate $cert
      }
      foreach ($roleIdItem in $roleIds) {
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/permissions/actions/" + $action + "_role/"
        $body = '{"operations": [' + $operations + '], "role_id": "' + $roleIdItem +
                '", "resource": "' + $hrefItem + '"}'
        $result = Invoke-RestMethod -Uri $uri -Body $body -Method Post `
                          -Certificate $cert
      }
    }
  } #end Process
} #end function Set-PulpPermission

# .ExternalHelp powershell-pulp-help.xml
Function New-PulpUser
{
  Param(
    [Parameter(Mandatory=$false)]         [string]          $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]         [int]             $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]         [string]          $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [string[]]         $Login,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)][string]           $Name,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)][string]     $Password) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    foreach ($loginName in $Login) {
      if (!$Name){ $newName = $loginName}
      else       { $newName = $Name }
      if (!$Password) {
        $newPassword = ([char[]](48..57) + [char[]](97..122) + [char[]](65..90) | sort {get-random})[0..12] -join ''
      }
      else { $newPassword = $Password }
      $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/users/"
      $body = '{"login": "' + $loginName + '", "password": "' + $newPassword +
              '", "name": "' + $newName + '"}'
      Invoke-RestMethod -Uri $uri -Method Post -Body $body -Certificate $cert
    }
  } #end Process
} #end function New-PulpUser

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpUser
{
  Param(
    [Parameter(Mandatory=$false)]        [string]           $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]        [int]              $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]        [string]           $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [PSCustomObject[]] $User) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    $users = $User | Select-Object -ExpandProperty login
    foreach ($item in $users) {
      $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/users/$item"
      $result = Invoke-RestMethod -Uri $uri -Method Delete -Certificate $cert
    }
  } #end Process
} #end function Remove-PulpUser

# .ExternalHelp powershell-pulp-help.xml
Function New-PulpRole
{
  Param(
    [Parameter(Mandatory=$false)]        [string]  $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]        [int]     $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]        [string]  $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [string[]]$Id,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)][string]  $DisplayName,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)][string]  $Description) #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    foreach ($roleId in $Id) {
      if (!$DisplayName) {
        $newDisplayName = 'null'
      }
      else { $newDisplayName = '"' + $DisplayName +'"' }
      if (!$Description) {
        $newDescription = 'null'
      }
      else { $newDescription = '"' + $Description +'"' }
      $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/roles/"
      $body = '{"role_id": "' + $roleId + '", "display_name": ' + $newDisplayName +
              ', "description": ' + $newDescription + '}'
      Invoke-RestMethod -Uri $uri -Method Post -Body $body -Certificate $cert
    }
  } #end Process
} #end function New-PulpRole

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpRole
{
  Param(
    [Parameter(Mandatory=$false)]        [string]           $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]        [int]              $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]        [string]           $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true)] [PSCustomObject[]] $Role) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
  }
  Process {
    $roles = $Role | Select-Object -ExpandProperty id
    foreach ($item in $roles) {
      $uri = "${Protocol}://${Server}:${Port}/pulp/api/v2/roles/$item"
      $result = Invoke-RestMethod -Uri $uri -Method Delete -Certificate $cert
    }
  } #end Process
} #end function Remove-PulpRole

# .ExternalHelp powershell-pulp-help.xml
Function Add-PulpRoleMember
{
  [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)]           [string]          $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]           [int]             $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]           [string]          $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$User,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [PSCustomObject[]]$Role,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]        $UserLogin,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [string[]]        $RoleId) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    If ( (!$Role) -and (!$RoleId) ) {
      Throw  "Please specify at least one role object or RoleId string"
      Return
    }
    $roleIds = @()
    If ($Role) {
      $RoleIds = $Role | Select-Object -ExpandProperty 'id'
    }
    If ($RoleId) {
      $roleIds += $RoleId
    }
  }
  Process {
    If ($User) {
      $UserLogin = $User | Select-Object -ExpandProperty 'login'
    }
    foreach ($userItem in $UserLogin) {
      foreach ($roleItem in $roleIds) {
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/roles/${roleItem}/users/"
        $body = '{"login": "' + $userItem + '"}'
        $result = Invoke-RestMethod -Uri $uri -Body $body -Method Post `
                          -Certificate $cert
      }
    }
  } #end Process
} #end function Add-PulpRoleMember

# .ExternalHelp powershell-pulp-help.xml
Function Remove-PulpRoleMember
{
  [Cmdletbinding(DefaultParameterSetName='Strings')]
  Param(
    [Parameter(Mandatory=$false)]           [string]          $Server   = 
                                       (Get-PulpLocalConfig -Server).Server,
    [Parameter(Mandatory=$false)]           [int]             $Port     =
                                       (Get-PulpLocalConfig -Port).Port,
    [Parameter(Mandatory=$false)]           [string]          $Protocol = 
                                       (Get-PulpLocalConfig -Protocol).Protocol,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Objects")] [PSCustomObject[]]$User,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [PSCustomObject[]]$Role,
    [Parameter(Mandatory=$true,
               Position=0,
               ValueFromPipeline=$true,
               ParameterSetName="Strings")] [string[]]        $UserLogin,
    [Parameter(Mandatory=$false,
               ValueFromPipeline=$false)]   [string[]]        $RoleId) 
    #end param
  Begin {
    $cert = Get-PulpCertificate -Server $Server -Port $Port -Protocol $Protocol
    If ( (!$Role) -and (!$RoleId) ) {
      Throw  "Please specify at least one role object or RoleId string"
      Return
    }
    $roleIds = @()
    If ($Role) {
      $RoleIds = $Role | Select-Object -ExpandProperty 'id'
    }
    If ($RoleId) {
      $roleIds += $RoleId
    }
  }
  Process {
    If ($User) {
      $UserLogin = $User | Select-Object -ExpandProperty 'login'
    }
    foreach ($userItem in $UserLogin) {
      foreach ($roleItem in $roleIds) {
        $uri = "${Protocol}://${Server}:${Port}" +
               "/pulp/api/v2/roles/${roleItem}/users/${userItem}/"
        $result = Invoke-RestMethod -Uri $uri -Method Delete -Certificate $cert
      }
    }
  } #end Process
} #end function Remove-PulpRoleMember

Export-ModuleMember -Function Add-PulpIso
Export-ModuleMember -Function Add-PulpPuppetModule
Export-ModuleMember -Function Add-PulpRoleMember
Export-ModuleMember -Function Add-PulpRpm
Export-ModuleMember -Function Copy-PulpIso
Export-ModuleMember -Function Copy-PulpPuppetModule
Export-ModuleMember -Function Copy-PulpRpm
Export-ModuleMember -Function Get-PulpCertificate
Export-ModuleMember -Function Get-PulpIso
Export-ModuleMember -Function Get-PulpIsoRepo
Export-ModuleMember -Function Get-PulpLocalConfig
Export-ModuleMember -Function Get-PulpPermission
Export-ModuleMember -Function Get-PulpPuppetModule
Export-ModuleMember -Function Get-PulpPuppetRepo
Export-ModuleMember -Function Get-PulpRole
Export-ModuleMember -Function Get-PulpRpm
Export-ModuleMember -Function Get-PulpRpmRepo
Export-ModuleMember -Function Get-PulpRpmRepoSyncSchedule
Export-ModuleMember -Function Get-PulpRpmRepoSyncStatus
Export-ModuleMember -Function Get-PulpTask
Export-ModuleMember -Function Get-PulpUser
Export-ModuleMember -Function New-PulpRole
Export-ModuleMember -Function New-PulpRpmRepo
Export-ModuleMember -Function New-PulpRpmRepoSyncSchedule
Export-ModuleMember -Function New-PulpUser
Export-ModuleMember -Function Publish-PulpIsoRepo
Export-ModuleMember -Function Publish-PulpPuppetRepo
Export-ModuleMember -Function Publish-PulpRpmRepo
Export-ModuleMember -Function Remove-PulpIso
Export-ModuleMember -Function Remove-PulpPuppetModule
Export-ModuleMember -Function Remove-PulpRole
Export-ModuleMember -Function Remove-PulpRoleMember
Export-ModuleMember -Function Remove-PulpRpm
Export-ModuleMember -Function Remove-PulpRpmRepo
Export-ModuleMember -Function Remove-PulpUser
Export-ModuleMember -Function Set-PulpLocalConfig
Export-ModuleMember -Function Set-PulpPermission
Export-ModuleMember -Function Start-PulpRpmRepoSync
Export-ModuleMember -Function Stop-PulpTask