diff --git a/PSGetInternal/PSGetInternal.psd1 b/PSGetInternal/PSGetInternal.psd1 index 5b37d61..9bc8969 100644 --- a/PSGetInternal/PSGetInternal.psd1 +++ b/PSGetInternal/PSGetInternal.psd1 @@ -4,7 +4,7 @@ RootModule = 'PSGetInternal.psm1' # Version number of this module. - ModuleVersion = '1.0.6' + ModuleVersion = '2.0.0' # Supported PSEditions # CompatiblePSEditions = @() @@ -25,7 +25,7 @@ Description = 'PowerShell GetInternal Module' # Minimum version of the PowerShell engine required by this module - # PowerShellVersion = '' + # PowerShellVersion = '7.4' (Microsoft.PowerShell.PSResourceGet installed per default on this version) # Name of the PowerShell host required by this module # PowerShellHostName = '' @@ -43,7 +43,9 @@ # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module - # RequiredModules = @() + RequiredModules = @( + 'Microsoft.PowerShell.PSResourceGet' + ) # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() @@ -65,6 +67,7 @@ 'Find-GIModule' 'Install-GIModule' 'Save-GIModule' + 'Set-GIRepoCredential' 'Set-GIRepository' 'Update-GIModule' ) diff --git a/PSGetInternal/functions/Find-GIModule.ps1 b/PSGetInternal/functions/Find-GIModule.ps1 index 4b8bd8f..bc0270e 100644 --- a/PSGetInternal/functions/Find-GIModule.ps1 +++ b/PSGetInternal/functions/Find-GIModule.ps1 @@ -8,6 +8,9 @@ .PARAMETER Name Name of the module. + + .PARAMETER RepositoryName + Name of the repository. .PARAMETER Credential Credential to get access to the configured Company-Internal repository. @@ -15,27 +18,34 @@ .EXAMPLE PS C:\> Find-GIModule - Will list all modules in the configured Company-Internal repository. + Will list all modules in the default configured Company-Internal repository. .EXAMPLE PS C:\> Find-GIModule -Name "Company-Module" - Will search the module "Company-Module" in the configured Company-Internal repository. + Will search the module "Company-Module" in the default configured Company-Internal repository. + + .EXAMPLE + PS C:\> Find-GIModule -Name "Company-Module" -RepositoryName "Company-Repository" + + Will search the module "Company-Module" in the "Company-Repository" repository. #> [CmdletBinding()] Param ( [string] $Name = "*", + + [ArgumentCompleter({ Get-RepoNameCompletion $args })] + [ValidateScript({ Assert-RepoName -Name $_ })] + [string] + $RepositoryName = (Get-DefaultRepo), [pscredential] - $Credential = (Get-RepoCredential) + $Credential = (Get-RepoCredential -RepositoryName $RepositoryName) ) - begin{ - if(-not $Script:Config){ - throw "Internal PSGallery not configured! Use Set-GIRepository to set up an internal Repository." - } - } + process { - Find-Module -Repository $Script:Config.Name -Name $Name -Credential $Credential + Write-Verbose "Seach Modules in $($RepositoryName)" + Find-PSResource -Repository $RepositoryName -Name $Name -Credential $Credential | Sort-Object -Unique Name, Version } } \ No newline at end of file diff --git a/PSGetInternal/functions/Install-GIModule.ps1 b/PSGetInternal/functions/Install-GIModule.ps1 index 31f7184..ec73308 100644 --- a/PSGetInternal/functions/Install-GIModule.ps1 +++ b/PSGetInternal/functions/Install-GIModule.ps1 @@ -9,6 +9,9 @@ .PARAMETER Name Name of the module. + .PARAMETER RepositoryName + Name of the repository. + .PARAMETER Credential Credential to get access to the configured Company-Internal repository. @@ -56,7 +59,12 @@ .EXAMPLE PS C:\> Install-GIModule -Name "Company-Module" - Will install the module "Company-Module" from the configured Company-Internal repository. + Will install the module "Company-Module" from the default configured Company-Internal repository. + + .EXAMPLE + PS C:\> Install-GIModule -Name "Company-Module" -RepositoryName "Company-Repository" + + Will install the module "Company-Module" from the "Company-Repository" repository. #> [CmdletBinding()] Param ( @@ -64,8 +72,13 @@ [string] $Name, + [ArgumentCompleter({ Get-RepoNameCompletion $args })] + [ValidateScript({ Assert-RepoName -Name $_ })] + [string] + $RepositoryName = (Get-DefaultRepo), + [pscredential] - $Credential = (Get-RepoCredential), + $Credential = (Get-RepoCredential -RepositoryName $RepositoryName), [switch] $Force, @@ -90,12 +103,9 @@ $Scope = 'CurrentUser' ) begin { - if (-not $Script:Config) { - throw "Internal PSGallery not configured! Use Set-GIRepository to set up an internal Repository." - } - + $param = @{ - Repository = $Script:Config.Name + Repository = $RepositoryName Name = $Name Credential = $Credential Scope = $Scope @@ -108,6 +118,6 @@ if ($RequiredVersion) { $param.RequiredVersion = $RequiredVersion } } process { - Install-Module @param + Install-PSResource @param } } \ No newline at end of file diff --git a/PSGetInternal/functions/Save-GIModule.ps1 b/PSGetInternal/functions/Save-GIModule.ps1 index 173ba3d..15302bf 100644 --- a/PSGetInternal/functions/Save-GIModule.ps1 +++ b/PSGetInternal/functions/Save-GIModule.ps1 @@ -11,6 +11,9 @@ .PARAMETER Path Path where the module should be saved. + + .PARAMETER RepositoryName + Name of the repository. .PARAMETER Credential Credential to get access to the configured Company-Internal repository. @@ -18,7 +21,7 @@ .EXAMPLE PS C:\> Save-GIModule -Name "Company-Module" -Path . - Will save the module "Company-Module" from the configured Company-Internal repository to the current path. + Will save the module "Company-Module" from the default configured Company-Internal repository to the current path. #> [CmdletBinding()] Param ( @@ -30,10 +33,15 @@ [string] $Path, + [ArgumentCompleter({ Get-RepoNameCompletion $args })] + [ValidateScript({ Assert-RepoName -Name $_ })] + [string] + $RepositoryName = (Get-DefaultRepo), + [pscredential] - $Credential = (Get-RepoCredential) + $Credential = (Get-RepoCredential -RepositoryName $RepositoryName) ) process { - Save-Module -Repository $Script:Config.Name -Name $Name -Credential $Credential -Path $Path + Save-PSResource -Repository $RepositoryName -Name $Name -Credential $Credential -Path $Path } } \ No newline at end of file diff --git a/PSGetInternal/functions/Set-GIRepoCredential.ps1 b/PSGetInternal/functions/Set-GIRepoCredential.ps1 new file mode 100644 index 0000000..09b462c --- /dev/null +++ b/PSGetInternal/functions/Set-GIRepoCredential.ps1 @@ -0,0 +1,35 @@ +function Set-GIRepoCredential { + <# + .SYNOPSIS + Creates or sets the repository credential. + + .DESCRIPTION + Creates or sets the repository credential for internal repositories. + + .PARAMETER RepositoryName + Name of the repository, to link the credentails. + + .PARAMETER Credential + Credentials that should be set. + + .EXAMPLE + C:\> Set-GIRepoCredential -RepositoryName "Company-Repository" -Credential $cred + + Will create or set for the repository "Company-Repository" the credential $cred. + #> + [CmdletBinding()] + param ( + [ArgumentCompleter({ Get-RepoNameCompletion $args })] + [ValidateScript({ Assert-RepoName -Name $_ })] + [Parameter(Mandatory)] + $RepositoryName, + + [Parameter(Mandatory)] + [pscredential] + $Credential + ) + process { + $credFile = Join-Path $Script:configPath "$($RepositoryName)_RepoCred.clixml" + $Credential | Export-Clixml -Path $credFile -Force + } +} \ No newline at end of file diff --git a/PSGetInternal/functions/Set-GIRepository.ps1 b/PSGetInternal/functions/Set-GIRepository.ps1 index 347bc92..5d04e06 100644 --- a/PSGetInternal/functions/Set-GIRepository.ps1 +++ b/PSGetInternal/functions/Set-GIRepository.ps1 @@ -9,7 +9,7 @@ .PARAMETER Name Name of repository which should be registered. - .PARAMETER SourceLocation + .PARAMETER Uri URL of the repository, which should be registered. .PARAMETER Credential @@ -19,21 +19,22 @@ Parameter to trust or untrust the source of the repository. .EXAMPLE - PS C:\> Set-GIRepository -Name "Contoso-Repository" -SourceLocation "https://pkgs.dev.azure.com/contosoINF/_packaging/InfernalAccounting/nuget/v2" -InstallationPolicy Trusted -Credential $cred + PS C:\> Set-GIRepository -Name "Company-Repository" -Uri "https://pkgs.dev.azure.com/contosoINF/_packaging/InfernalAccounting/nuget/v2" -InstallationPolicy Trusted -Credential $cred - Will register the trusted repository "Contoso-Repository" with SourceLocation "https://pkgs.dev.azure.com/contosoINF/_packaging/InfernalAccounting/nuget/v2". + Will register the trusted repository "Company-Repository" with Uri "https://pkgs.dev.azure.com/contosoINF/_packaging/InfernalAccounting/nuget/v2". And will generate a config and credential file. #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions','')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] [CmdletBinding()] Param ( [Parameter(Mandatory)] [string] $Name, + [Alias('SourceLocation')] [Parameter(Mandatory)] [uri] - $SourceLocation, + $Uri, [Parameter(Mandatory)] [pscredential] @@ -41,23 +42,27 @@ [ValidateSet('Trusted', 'Untrusted')] [string] - $InstallationPolicy = 'Trusted' + $InstallationPolicy = 'Trusted', + + [switch] + $Default ) process { - $existingRepo = Get-PSRepository -Name $Name -ErrorAction Ignore + $existingRepo = Get-PSResourceRepository -Name $Name -ErrorAction Ignore if (-not $existingRepo) { try { - Register-PSRepository -Name $Name -SourceLocation $SourceLocation -InstallationPolicy $InstallationPolicy -Credential $Credential -ErrorAction Stop + Register-PSResourceRepository -Name $Name -Uri $Uri -Trusted:$($InstallationPolicy -eq "Trusted") -ErrorAction Stop } catch { Write-Warning -Message "Error register Company-Internal Repository: $_" return } - }else{ - if (($existingRepo.SourceLocation -ne $SourceLocation) -or ($existingRepo.InstallationPolicy -ne $InstallationPolicy)) { + } + else { + if (($existingRepo.Uri -ne $Uri) -or ($existingRepo.Trusted -ne ($InstallationPolicy -eq "Trusted"))) { try { - Unregister-PSRepository -Name $Name -ErrorAction Stop - Set-PSRepository -Name $Name -SourceLocation $SourceLocation -InstallationPolicy $InstallationPolicy -Credential $Credential -ErrorAction Stop + Unregister-PSResourceRepository -Name $Name -ErrorAction Stop + Register-PSResourceRepository -Name $Name -Uri $Uri -Trusted:$($InstallationPolicy -eq "Trusted") -ErrorAction Stop } catch { Write-Warning -Message "Error to update Company-Internal Repository: $_" @@ -65,17 +70,12 @@ } } } - - $credFile = Join-Path $Script:configPath "RepoCred.clixml" - $Credential | Export-Clixml -Path $credFile -Force - $repository = [PSCustomObject]@{ - Name = $Name - SourceLocation = $SourceLocation - InstallationPolicy = $InstallationPolicy + Set-GIRepoCredential -RepositoryName $Name -Credential $Credential + + if ($Default) { + $defaultRepoFile = Join-Path $Script:configPath "DefaultRepo.clixml" + $Name | Export-Clixml -Path $defaultRepoFile -Force } - $repoFile = Join-Path $Script:configPath "config.clixml" - $repository | Export-Clixml -Path $repoFile -Force - $Script:Config = $repository } } \ No newline at end of file diff --git a/PSGetInternal/functions/Update-GIModule.ps1 b/PSGetInternal/functions/Update-GIModule.ps1 index bf2d6be..584d208 100644 --- a/PSGetInternal/functions/Update-GIModule.ps1 +++ b/PSGetInternal/functions/Update-GIModule.ps1 @@ -8,6 +8,9 @@ .PARAMETER Name Name of the module. + + .PARAMETER RepositoryName + Name of the repository. .PARAMETER Credential Credential to get access to the configured Company-Internal repository. @@ -49,6 +52,11 @@ PS C:\> Update-GIModule -Name "Company-Module" Will update the module "Company-Module" from the configured Company-Internal repository. + + .EXAMPLE + PS C:\> Update-GIModule -Name "Company-Module" -RepositoryName "Company-Repository" + + Will update the module "Company-Module" from the "Company-Internal" repository. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions','')] [CmdletBinding()] @@ -57,9 +65,14 @@ [string] $Name, - [pscredential] - $Credential = (Get-RepoCredential), + [ArgumentCompleter({ Get-RepoNameCompletion $args })] + [ValidateScript({ Assert-RepoName -Name $_ })] + [string] + $RepositoryName, + [pscredential] + $Credential = (Get-RepoCredential -RepositoryName $RepositoryName), + [switch] $Force, @@ -77,13 +90,10 @@ ) begin { - if (-not $Script:Config) { - throw "Internal PSGallery not configured! Use Set-GIRepository to set up an internal Repository." - } - $param = @{ Name = $Name Credential = $Credential + Repository = $RepositoryName } if ($Force) { $param.Force = $Force } if ($AllowClobber) { $param.AllowClobber = $AllowClobber } @@ -92,6 +102,6 @@ if ($RequiredVersion) { $param.RequiredVersion = $RequiredVersion } } process { - Update-Module @param + Update-PSResource @param } } \ No newline at end of file diff --git a/PSGetInternal/internal/functions/Assert-RepoName.ps1 b/PSGetInternal/internal/functions/Assert-RepoName.ps1 new file mode 100644 index 0000000..8e541ca --- /dev/null +++ b/PSGetInternal/internal/functions/Assert-RepoName.ps1 @@ -0,0 +1,34 @@ +function Assert-RepoName { + <# + .SYNOPSIS + Asserts a repository name actually exists. + + .DESCRIPTION + Asserts a repository name actually exists. + Used in validation scripts to ensure proper repository names were provided. + + .PARAMETER Name + The name of the repository to verify. + + .EXAMPLE + PS C:\> Assert-repositoryName -Name $_ + + Returns $true if the repository exists and throws a terminating exception if not so. + #> + [OutputType([bool])] + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [AllowNUll()] + [string] + $Name + ) + process { + if ((Get-PSResourceRepository).Name -contains $Name) { return $true } + + $repoNames = (Get-PSResourceRepository).Name -join ', ' + Write-Warning "Invalid repository name: '$Name'. Legal repository names: $repoNames" + Invoke-TerminatingException -Cmdlet $PSCmdlet -Message "Invalid repository name: '$Name'. Legal repository names: $repoNames" + } +} \ No newline at end of file diff --git a/PSGetInternal/internal/functions/Get-DefaultRepo.ps1 b/PSGetInternal/internal/functions/Get-DefaultRepo.ps1 new file mode 100644 index 0000000..0af99da --- /dev/null +++ b/PSGetInternal/internal/functions/Get-DefaultRepo.ps1 @@ -0,0 +1,25 @@ +function Get-DefaultRepo { + [CmdletBinding()] + param () + process { + $defaultRepoFile = Join-Path $Script:configPath "DefaultRepo.clixml" + $existingRepoNames = (Get-PSResourceRepository).Name + + if (-not (Test-Path -Path $defaultRepoFile)) { + if ("PSGallery" -in $existingRepoNames) { + "PSGallery" + return + } + Write-Warning "No default repository defined and could not found 'PSGallery' as repository" + Invoke-TerminatingException -Cmdlet $PSCmdlet -Message "No default repository defined and could not found 'PSGallery' as repository" + } + + $defaultRepoName = Import-Clixml $defaultRepoFile + + if (-not ($defaultRepoName -in $existingRepoNames)) { + Write-Warning "The default repository $($defaultRepoName) could not found as repository. Legal repository names: $($existingRepoNames -join ', ')" + Invoke-TerminatingException -Cmdlet $PSCmdlet -Message "The default repository $($defaultRepoName) could not found as repository. Legal repository names: $($existingRepoNames -join ', ')" + } + $defaultRepoName + } +} \ No newline at end of file diff --git a/PSGetInternal/internal/functions/Get-RepoCredential.ps1 b/PSGetInternal/internal/functions/Get-RepoCredential.ps1 index 36a1b34..6335654 100644 --- a/PSGetInternal/internal/functions/Get-RepoCredential.ps1 +++ b/PSGetInternal/internal/functions/Get-RepoCredential.ps1 @@ -13,9 +13,18 @@ #> [OutputType([pscredential])] [CmdletBinding()] - param() + param( + [Parameter(Mandatory)] + $RepositoryName + ) - $credFilePath = Join-Path $Script:ConfigPath "RepoCred.clixml" + + $credFilePath = Join-Path $Script:ConfigPath "$($RepositoryName)_RepoCred.clixml" + + if(-not (Test-Path -Path $credFilePath)){ + Write-Verbose "No existing credential file for $($RepositoryName)." + return + } Import-Clixml $credFilePath } \ No newline at end of file diff --git a/PSGetInternal/internal/functions/Get-RepoNameCompletion.ps1 b/PSGetInternal/internal/functions/Get-RepoNameCompletion.ps1 new file mode 100644 index 0000000..f93fd1f --- /dev/null +++ b/PSGetInternal/internal/functions/Get-RepoNameCompletion.ps1 @@ -0,0 +1,39 @@ +function global:Get-RepoNameCompletion { + <# + .SYNOPSIS + Returns the values to complete for.repository names. + + .DESCRIPTION + Returns the values to complete for.repository names. + Use this command in argument completers. + + .PARAMETER ArgumentList + The arguments an argumentcompleter receives. + The third item will be the word to complete. + + .EXAMPLE + PS C:\> Get-ServiceCompletion -ArgumentList $args + + Returns the values to complete for.repository names. + #> + [OutputType([System.Management.Automation.CompletionResult])] + [CmdletBinding()] + param ( + $ArgumentList + ) + process { + $wordToComplete = $ArgumentList[2].Trim("'`"") + foreach ($repo in Get-PSResourceRepository) { + if ($repo.Name -notlike "$($wordToComplete)*") { continue } + + $text = if ($repo.Name -notmatch '\s') { $repo.Name } else { "'$($repo.Name)'" } + [System.Management.Automation.CompletionResult]::new( + $text, + $text, + 'Text', + $repo.Uri + ) + } + } +} +$ExecutionContext.InvokeCommand.GetCommand("Get-RepoNameCompletion","Function").Visibility = 'Private' \ No newline at end of file diff --git a/PSGetInternal/internal/functions/Invoke-TerminatingException.ps1 b/PSGetInternal/internal/functions/Invoke-TerminatingException.ps1 new file mode 100644 index 0000000..975587c --- /dev/null +++ b/PSGetInternal/internal/functions/Invoke-TerminatingException.ps1 @@ -0,0 +1,70 @@ +function Invoke-TerminatingException +{ +<# + .SYNOPSIS + Throw a terminating exception in the context of the caller. + + .DESCRIPTION + Throw a terminating exception in the context of the caller. + Masks the actual code location from the end user in how the message will be displayed. + + .PARAMETER Cmdlet + The $PSCmdlet variable of the calling command. + + .PARAMETER Message + The message to show the user. + + .PARAMETER Exception + A nested exception to include in the exception object. + + .PARAMETER Category + The category of the error. + + .PARAMETER ErrorRecord + A full error record that was caught by the caller. + Use this when you want to rethrow an existing error. + + .EXAMPLE + PS C:\> Invoke-TerminatingException -Cmdlet $PSCmdlet -Message 'Unknown calling module' + + Terminates the calling command, citing an unknown caller. +#> + [CmdletBinding()] + Param ( + [Parameter(Mandatory = $true)] + $Cmdlet, + + [string] + $Message, + + [System.Exception] + $Exception, + + [System.Management.Automation.ErrorCategory] + $Category = [System.Management.Automation.ErrorCategory]::NotSpecified, + + [System.Management.Automation.ErrorRecord] + $ErrorRecord + ) + + process{ + if ($ErrorRecord -and -not $Message) { + $Cmdlet.ThrowTerminatingError($ErrorRecord) + } + + $exceptionType = switch ($Category) { + default { [System.Exception] } + 'InvalidArgument' { [System.ArgumentException] } + 'InvalidData' { [System.IO.InvalidDataException] } + 'AuthenticationError' { [System.Security.Authentication.AuthenticationException] } + 'InvalidOperation' { [System.InvalidOperationException] } + } + + + if ($Exception) { $newException = $Exception.GetType()::new($Message, $Exception) } + elseif ($ErrorRecord) { $newException = $ErrorRecord.Exception.GetType()::new($Message, $ErrorRecord.Exception) } + else { $newException = $exceptionType::new($Message) } + $record = [System.Management.Automation.ErrorRecord]::new($newException, (Get-PSCallStack)[1].FunctionName, $Category, $Target) + $Cmdlet.ThrowTerminatingError($record) + } +} \ No newline at end of file diff --git a/PSGetInternal/internal/scripts/Initialize.ps1 b/PSGetInternal/internal/scripts/Initialize.ps1 index 6d6e564..f7947f0 100644 --- a/PSGetInternal/internal/scripts/Initialize.ps1 +++ b/PSGetInternal/internal/scripts/Initialize.ps1 @@ -1,14 +1,14 @@ -$Script:ConfigPath = Join-Path $env:LOCALAPPDATA "PowerShell\PSGetInternal" -$packagePath = Join-Path $env:LOCALAPPDATA "PackageManagement\ProviderAssemblies\nuget\2.8.5.208\Microsoft.PackageManagement.NuGetProvider.dll" +$localAppData = $env:LOCALAPPDATA -if(-not (Test-Path -Path $packagePath)){ - $null = New-Item -ItemType Directory -Path (Split-Path $packagePath) -Force - Copy-Item -Path "$Script:ModuleRoot\bin\Microsoft.PackageManagement.NuGetProvider.dll" -Destination $packagePath -Force -Recurse +if ($IsLinux -or $IsMacOS){ + $localAppData = $Env:XDG_CONFIG_HOME + if(-not $localAppData){ + $localAppData = Join-Path $HOME ".config" + } } +$Script:ConfigPath = Join-Path $localAppData "PowerShell\PSGetInternal" + if(-not (Test-Path -Path $Script:ConfigPath)){ $null = New-Item -ItemType Directory -Path $Script:ConfigPath -Force -} -if(Test-Path -Path (Join-Path $Script:ConfigPath 'config.clixml')){ - $script:config = Import-Clixml -Path (Join-Path $Script:ConfigPath 'config.clixml') -ErrorAction Ignore } \ No newline at end of file diff --git a/README.md b/README.md index 10676cd..ca4c321 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The module itself and the related function will be used to call the internal rep To use this module directly, you need to install it from the PowerShell Gallery: ```powershell -Install-Module PSGetInternal -Scope CurrentUser +Install-PSResource PSGetInternal -Scope CurrentUser ``` Alternatively, you may want to deploy it via bootstrap script to solve the fundamental chicken/egg problem of deploying the tools to deploy tools. @@ -27,11 +27,17 @@ Only use one time to register the repository. Is not needed, if bootstrap got used. ```powershell -# Register the trusted repository "Internal-Repository" with SourceLocation "". And generate a config and credential file. +# Register the trusted repository "Internal-Repository" with SourceLocation "". Generate a credential file for this repository. $cred = Get-Credential -UserName "" -Message "Provide PAT used to authenticate to the internal PowerShell Gallery" Set-GIRepository -Name "Internal-Repository" -SourceLocation "" -InstallationPolicy "Trusted" -Credential $cred ``` +```powershell +# Register the trusted repository "Internal-Repository" with SourceLocation "". Generate a credential file for this repository and mark it as default. +$cred = Get-Credential -UserName "" -Message "Provide PAT used to authenticate to the internal PowerShell Gallery" +Set-GIRepository -Name "Internal-Repository" -SourceLocation "" -InstallationPolicy "Trusted" -Credential $cred -Default +``` + ```powershell # Install the module "" from the configured Internal-Repository repository. Install-GIModule -Name "" @@ -47,7 +53,7 @@ Install-GIModule -Name "" ```powershell # Save the module "PSGetInternal" to "". -Save-Module -Name "PSGetInternal" -Path "" -Repository "PSGallery" +Save-PSResource -Name "PSGetInternal" -Path "" -Repository "PSGallery" ``` 4. Edit the bootstrap script to your internal repository. Add your personal default settings under the first paramblock: diff --git a/bootstrap.ps1 b/bootstrap.ps1 index f8c27bd..352e151 100644 --- a/bootstrap.ps1 +++ b/bootstrap.ps1 @@ -98,10 +98,20 @@ function Install-NugetTools { throw "Please install the module 'PSGetInternal' and store this script in the same folder" } - $modulesRoot = $env:PSModulePath -split ';' | Where-Object { $_ -match 'documents' } | Select-Object -First 1 + $modulesRoot = $env:PSModulePath -split ';' | Where-Object { $_ -match 'documents|users' } | Select-Object -First 1 + Copy-Item -Path "$($PSScriptRoot)\PSGetInternal" -Destination $modulesRoot -Force -Recurse - Copy-Item -Path "$($PSScriptRoot)\PSGetInternal" -Destination $modulesRoot -Force -Recurse - + $psResourceModule = Get-Module -Name Microsoft.PowerShell.PSResourceGet -ListAvailable | Sort-Object -Descending Version | Select-Object -First 1 + + $bootstrapGetVersion = Get-Item -Path "$($PSScriptRoot)\Microsoft.PowerShell.PSResourceGet\*\Microsoft.PowerShell.PSResourceGet.psd1" | ForEach-Object { + (Import-PowerShellDataFile -LiteralPath $_.FullName).ModuleVersion -as [version] + } | Sort-Object -Descending | Select-Object -First 1 + + if($bootstrapGetVersion -lt $psResourceModule.Version){ + return + } + + Copy-Item -Path "$($PSScriptRoot)\Microsoft.PowerShell.PSResourceGet" -Destination $modulesRoot -Force -Recurse } #endregion functions diff --git a/build/vsts-build.ps1 b/build/vsts-build.ps1 index 7beb35e..78f9e7e 100644 --- a/build/vsts-build.ps1 +++ b/build/vsts-build.ps1 @@ -64,7 +64,7 @@ Remove-Item -Path "$($publishDir.FullName)\PSGetInternal\functions" -Recurse -Fo if ($AutoVersion) { Write-Host "Updating module version numbers." - try { [version]$remoteVersion = (Find-Module 'PSGetInternal' -Repository $Repository -ErrorAction Stop).Version } + try { [version]$remoteVersion = (Find-PSResource 'PSGetInternal' -Repository $Repository -ErrorAction Stop).Version } catch { throw "Failed to access $($Repository) : $_" @@ -75,7 +75,7 @@ if ($AutoVersion) } $newBuildNumber = $remoteVersion.Build + 1 [version]$localVersion = (Import-PowerShellDataFile -Path "$($publishDir.FullName)\PSGetInternal\PSGetInternal.psd1").ModuleVersion - Update-ModuleManifest -Path "$($publishDir.FullName)\PSGetInternal\PSGetInternal.psd1" -ModuleVersion "$($localVersion.Major).$($localVersion.Minor).$($newBuildNumber)" + Update-PSResourceManifest -Path "$($publishDir.FullName)\PSGetInternal\PSGetInternal.psd1" -ModuleVersion "$($localVersion.Major).$($localVersion.Minor).$($newBuildNumber)" } #endregion Updating the Module Version diff --git a/build/vsts-prerequisites.ps1 b/build/vsts-prerequisites.ps1 index 5610148..c21fd34 100644 --- a/build/vsts-prerequisites.ps1 +++ b/build/vsts-prerequisites.ps1 @@ -20,6 +20,6 @@ foreach ($dependency in $data.RequiredModules) { foreach ($module in $modules) { Write-Host "Installing $module" -ForegroundColor Cyan - Install-Module $module -Force -SkipPublisherCheck -Repository $Repository + Install-PSResource $module -Force -SkipPublisherCheck -Repository $Repository Import-Module $module -Force -PassThru } \ No newline at end of file