PSArtifactory.psm1
using namespace Microsoft.PowerShell.SHiPS New-Alias -Name ls -Value "Get-ChildItem" -Force if(Test-Path -Path (Join-Path $HOME ".PSArtifactory") ){ }else{ mkdir -p (Join-Path $HOME ".PSArtifactory") } Function Clear-AFCredential { Remove-Item -Path (Get-AFCredentialPath) -Force } function Clear-AFTrashCan { Invoke-AFApi -Path '/trash/empty' -Method "POST" } function Get-AFChildItem { param ( # Parameter help description [Parameter(Mandatory)] [String] $SourcePath, # Parameter help description [Parameter(Mandatory)] [String] $TargetPath, # Parameter help description [Parameter()] [Switch] $DryRun, # Parameter help description [Parameter()] [Int] $SuppressLayouts=1, # Parameter help description [Parameter()] [Switch] $FailFast ) $Path = "/api/copy/$SourcePath?to=/$TargetPath" Invoke-AFApi -Path $Path -Method "POST" } function Get-AFChildItem { param ( # Parameter help description [Parameter()][ValidateNotNullOrEmpty()] [String] $Repository = (Get-AFContext).Repository, # Parameter help description [Parameter()] [Int32] $Depth = 10, # Parameter help description [Parameter()] [switch] $IncludeFolders, # Parameter help description [Parameter()] [String] $Path ) $listFolders = 0 if($IncludeFolders){$listFolders = 1} if($Path){ $Uri = "/storage/$($Repository)$($Path)" #?includeRootPath=0&deep=0&depth=$Depth&mdTimestamps=1&listFolders=$listFolders" }else{ $Uri = "/storage/$($Repository)" #?includeRootPath=0&deep=0&depth=$Depth&mdTimestamps=1&listFolders=$listFolders" } Invoke-AFApi -Path $Uri # $Results # $Results } function Get-AFContext { Get-Content -Raw -Path (Get-AFContextPath) | ConvertFrom-Json } Function Get-AFFile{ param( # Parameter help description [Parameter(Mandatory)] [String] $AFPath, # Parameter help description [Parameter(Mandatory)] [String] $LocalPath ) Invoke-AFRequest -OutFile $LocalPath -Path $AFPath } function Get-AFRepository { [CmdletBinding(DefaultParameterSetName='Plural')] param ( # Parameter help description [Parameter(ParameterSetName='Single')] [String] $Key, # Parameter help description [Parameter(ParameterSetName='Plural')] [ValidateSet("local","remote","virtual","distribution")] [String] $Type ) begin { } process { $Path = "/repositories" if($Key){ $Path += "/$Key" } if($Type){ $Path += "?type=$Type" } (Invoke-AFApi -Path $Path) | % { [PSCustomObject]@{Url = $PSItem.url; Name = $PSItem.key} # [Repository]::new($PSItem.key, $PSItem.url) } } end { } } <# .SYNOPSIS Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet .INPUTS Inputs to this cmdlet (if any) .OUTPUTS Output from this cmdlet (if any) .NOTES General notes .COMPONENT The component this cmdlet belongs to .ROLE The role this cmdlet belongs to .FUNCTIONALITY The functionality that best describes this cmdlet function Verb-Noun { [CmdletBinding(DefaultParameterSetName='Parameter Set 1', SupportsShouldProcess=$true, PositionalBinding=$false, HelpUri = 'http://www.microsoft.com/', ConfirmImpact='Medium')] [Alias()] [OutputType([String])] Param ( # Param1 help description [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, ParameterSetName='Parameter Set 1')] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [ValidateCount(0,5)] [ValidateSet("sun", "moon", "earth")] [Alias("p1")] $Param1, # Param2 help description [Parameter(ParameterSetName='Parameter Set 1')] [AllowNull()] [AllowEmptyCollection()] [AllowEmptyString()] [ValidateScript({$true})] [ValidateRange(0,5)] [int] $Param2, # Param3 help description [Parameter(ParameterSetName='Another Parameter Set')] [ValidatePattern("[a-z]*")] [ValidateLength(0,15)] [String] $Param3 ) begin { } process { if ($pscmdlet.ShouldProcess("Target", "Operation")) { } } end { } } #> Function Get-AFSystemInfo{ param() Invoke-AFApi -Path '/system' } function Get-AFToken { (Invoke-AFApi -Path '/security/token').tokens } Function New-AFToken{ param( # Parameter help description [Parameter()] [String][Alias("AccessKey","UserName")] $Subject = ([Guid]::newGuid().Guid), # Parameter help description [Parameter()] [String] $ExpirySec = 3600, # Parameter help description [Parameter()] [switch] $Refreshable, # Parameter help description [Parameter()] [string[]] $GroupName = @("readers") ) $Body = @{ username = $Subject scope = "member-of-groups:$($GroupName -join ',')" expires_in = $ExpirySec } if($Refreshable) { $Body += @{ refreshable = $true} } Invoke-AFApi -Path '/security/token' -Method Post -Body $Body -ContentType 'application/x-www-form-urlencoded' } Function Ping-AFServer{ [cmdletbinding()] param() $TargetUri = (Get-AFContext).APIUri + '/system/ping' Write-Verbose "Pinging $TargetUri" if((Invoke-WebRequest -Method Get -Uri $TargetUri) -like "ok"){ Write-Output $true }else { Write-Output $false } } Function Register-AFDrive{ New-PSDrive -name PSArtifactory -psprovider SHiPS -root "PSArtifactory#Root" } Function Remove-AFItem { param( # Parameter help description [Parameter()] [String] $Repository = (Get-AFContext).Repository, # Parameter help description [Parameter(Mandatory)] [String] $Uri ) if($Repository -eq $null){ throw "Reposiotry null. Configure using Set-AFContext -Repository 'RepositoryName' -APIUri ..." } $Uri = "/$Repository$Uri" Invoke-AFRequest -Path $Uri -Method Delete } function Revoke-AFToken{ param( # Parameter help description [Parameter(Mandatory)] [String] $Id ) $Body = @{ token_id = $Id } Invoke-AFApi -Path '/security/token/revoke' -Method Post -Body $Body } function Set-AFContext { [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] param( [Parameter()] [ValidateNotNullOrEmpty()] [string] $Repository, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $APIUri, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $BaseUri ) BEGIN { if (-not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') } if (-not $PSBoundParameters.ContainsKey('WhatIf')) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') } } PROCESS { $Prop = @{ APIUri = $APIUri Repository = $Repository BaseUri = $BaseUri } $Prop | ConvertTo-Json | Out-File -FilePath (Get-AFContextPath) } END { } } function Set-AFCredential { [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] param( [Parameter( ParameterSetName='Basic' )] [ValidateNotNullOrEmpty()] [String] $UserId, [Parameter( ParameterSetName='Basic' )] [ValidateNotNullOrEmpty()] [String] $Password, [Parameter( ParameterSetName='AccessToken' )] [ValidateNotNullOrEmpty()] [string] $Token, [Parameter( ParameterSetName='ImportFromDisk' )] [Switch] $ImportFromDisk ) BEGIN { if (-not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference') } if (-not $PSBoundParameters.ContainsKey('WhatIf')) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') } } PROCESS { switch($PSCmdlet.ParameterSetName){ "Basic" { # $SecPassword = ConvertTo-SecureString $Password -AsPlainText -Force $SecPassword = $Password } "AccessToken" { $UserId = "AccessToken" # $SecPassword = ConvertTo-SecureString $Token -AsPlainText -Force $SecPassword = $Token } } # $PSCred = New-Object System.Management.Automation.PsCredential($UserId,$SecPassword) $PSCred = @{ Username = $UserId Password = $SecPassword } New-Object -TypeName PSObject -Property (@{ Credential = $PSCred CredentialType = $PSCmdlet.ParameterSetName }) | ConvertTo-Json | Out-File -FilePath (Get-AFCredentialPath) } END { } } Function Get-AFContextPath { (Join-Path (Join-Path $HOME ".PSArtifactory") "context") } Function Get-AFCredential { [cmdletbinding()] param() # Write-Verbose "The full key is not returned for security!" # Write-Host $script:AFCredential.Credential.GetNetworkCredential().Password # if(-not $script:AFCredential){ # throw "No credentials found! Try running Set-AFCredential" # }else{ # Write-Verbose "Found Credentials of type $($script:AFCredential.CredentialType)" # } if(-not (Test-Path -Path (Get-AFCredentialPath))){ throw "No credentials found! Set them with Set-AFCredential" } $Credential = Get-Content -Raw -Path (Get-AFCredentialPath) | ConvertFrom-Json $SecPassword = ConvertTo-SecureString $Credential.Credential.Password -AsPlainText -Force $PSCred = New-Object System.Management.Automation.PsCredential($Credential.Credential.Username, $SecPassword) $Credential.Credential = $PSCred $Credential } Function Get-AFCredentialPath { (Join-Path (Join-Path $HOME ".PSArtifactory") "credential") } function Invoke-AFApi { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter()] [ValidateSet('Delete', 'Get', 'Post', 'Put')] [string] $Method = 'Get', [Parameter()] [ValidateNotNullOrEmpty()] [hashtable] $Headers = @{}, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Accept, [Parameter()] [ValidateNotNullOrEmpty()] [HashTable] $Body, [Parameter()] [ValidateNotNullOrEmpty()] [string] $ContentType = 'application/x-www-form-urlencoded', [Parameter()] [ValidateSet("RepoUri","APIUri")] [string] $Uri = "APIUri" ) $FullUri = (Get-AFContext).APIUri $IwrParams = @{ Uri = $FullUri + $Path Method = $Method ContentType = $ContentType } $Cred = Get-AFCredential switch ($Cred.CredentialType) { "Basic" { Write-Verbose "BASIC AUTH USED" $IwrParams += @{ Credential = $Cred.Credential } } "AccessToken" { Write-Verbose "BEARER AUTH USED" $IwrParams += @{ Headers = @{ Bearer = $Cred.Credential.GetNetworkCredential().Password} } } } if($Body){ $IwrParams += @{ Body = $Body} } # Write-Host ($IwrParams | ConvertTo-Json -Depth 4) try{ Invoke-RestMethod @IwrParams -AllowUnencryptedAuthentication } catch { $_.Exception.Message } } function Invoke-AFRequest { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter()] [ValidateSet('Delete', 'Get', 'Post', 'Put')] [string] $Method = 'Get', [Parameter()] [ValidateNotNullOrEmpty()] [hashtable] $Headers = @{}, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Accept, [Parameter()] [ValidateNotNullOrEmpty()] [HashTable] $Body, [Parameter()] [ValidateNotNullOrEmpty()] [string] $ContentType = 'application/x-www-form-urlencoded', [Parameter()] [string] $Uri, [Parameter()] [string] $OutFile ) $FullUri = (Get-AFContext).BaseUri $IwrParams = @{ Uri = $FullUri + $Path Method = $Method ContentType = $ContentType AllowUnencryptedAuthentication = $true } if($Uri){ $IwrParams.Uri = $Uri } $Cred = Get-AFCredential switch ($Cred.CredentialType) { "Basic" { Write-Verbose "BASIC AUTH USED" $IwrParams += @{ Credential = $Cred.Credential } } "AccessToken" { Write-Verbose "BEARER AUTH USED" $IwrParams += @{ Headers = @{ Bearer = $Cred.Credential.GetNetworkCredential().Password} } } } if($Body){ $IwrParams += @{ Body = $Body} } if($OutFile){ $IwrParams += @{ OutFile = $OutFile} } $IwrParams | ConvertTo-Json -Depth 4 try{ Invoke-RestMethod @IwrParams } catch { $_.Exception | ConvertTo-Json -Depth 1 } } class RepositoryRoot: SHiPSDirectory { RepositoryRoot([String]$Name): base($Name) #Implies Root Folder { } [object[]] GetChildItem() { return (Get-AFRepository) | ForEach-Object { [RepositoryFolder]::new($PSItem.Name,$PSItem.Name) } } } # class Repository : SHiPSDirectory # { # [string]$Name # [string]$Uri # Repository([string]$Name, [String]$Uri): base($Name) # { # $this.Name = $Name # $this.Uri = $Uri # } # [object[]] GetChildItem() # { # return (Get-RepoItems) # } # } Function Get-RepoItems { foreach($Item in Get-AFChildItem -Path $this.Path){ foreach($Child in $Item.children){ # Write-Host "Processing $($PSItem | ConvertTo-Json -Compress)" $Name = $Child.uri.split("/") $Name = $Name[$Name.Count-1] # Write-Host "NAME: $Name" if($Child.folder -eq $true){ [RepositoryFolder]::new($Name, $this.Path + $Child.uri, $this.Repository ,$Item.uri + $Child.uri) }else{ # [RepositoryFolder]::new($Name, $this.Path + $PSItem.uri) [RepositoryItem]::new($Name, $this.Path + $Child.uri, $this.Repository, $Item.uri + $Child.uri) } } } } Class RepositoryFolder: SHiPSDirectory { [String]$Path = "" [String]$Uri = "" [String]$Repository = "" RepositoryFolder([String]$Name, [String]$Repository): base($Name) #Implies Root Folder { $this.Repository = $Repository } RepositoryFolder([String]$Name, [String]$Path, [String]$Repository,[String]$Uri): base($Name) #Implies Root Folder { $this.Path = $Path $this.Uri = $Uri $this.Repository = $Repository } [object[]] GetChildItem() { return (Get-RepoItems) } } class RepositoryItem : SHiPSLeaf { [String]$Key [String]$Path [String]$Uri [String]$Repository = "" RepositoryItem([String]$Key,[String]$Path, [String]$Repository, [String]$Uri):base($Key) { $this.Key = $Key $this.Path = $Path $this.Uri = $Uri $this.Repository = $Repository } [bool] RemoveItem(){ Write-Host "Removing Item: $($this.Uri)" return true } } class Root : SHiPSDirectory { Root([string]$Name): base($Name) { $Credential = Get-AFCredential $Context = Get-AFContext } [object[]] GetChildItem() { return @( [RepositoryRoot]::new("Repositories"), [RepositoryRoot]::new("Users") ) } } # class Root : SHiPSDirectory # { # Root([string]$Name): base($Name){ # } # [object[]] GetChildItem() # { # return @(Get-RootFolders) # } # } # Function Get-RootFolders(){ # $RootFolders.Values # } # $Script:RootFolders = @( # Repositories = [Repositories]::new(), # Users = [Repositories]::new() # ) |