PSModule.psm1
######################################################################################### # # Copyright (c) Microsoft Corporation. All rights reserved. # # PowerShellGet Module # ######################################################################################### Microsoft.PowerShell.Core\Set-StrictMode -Version Latest #region script variables # Check if this is nano server. [System.Runtime.Loader.AssemblyLoadContext] is only available on NanoServer $script:isNanoServer = $null -ne ('System.Runtime.Loader.AssemblyLoadContext' -as [Type]) $script:IsInbox = $PSHOME.EndsWith('\WindowsPowerShell\v1.0', [System.StringComparison]::OrdinalIgnoreCase) $script:IsWindows = (-not (Get-Variable -Name IsWindows -ErrorAction Ignore)) -or $IsWindows $script:IsLinux = (Get-Variable -Name IsLinux -ErrorAction Ignore) -and $IsLinux $script:IsOSX = (Get-Variable -Name IsOSX -ErrorAction Ignore) -and $IsOSX $script:IsCoreCLR = (Get-Variable -Name IsCoreCLR -ErrorAction Ignore) -and $IsCoreCLR if($script:IsInbox) { $script:ProgramFilesPSPath = Microsoft.PowerShell.Management\Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell" } else { $script:ProgramFilesPSPath = $PSHome } if($script:IsInbox) { try { $script:MyDocumentsFolderPath = [Environment]::GetFolderPath("MyDocuments") } catch { $script:MyDocumentsFolderPath = $null } $script:MyDocumentsPSPath = if($script:MyDocumentsFolderPath) { Microsoft.PowerShell.Management\Join-Path -Path $script:MyDocumentsFolderPath -ChildPath "WindowsPowerShell" } else { Microsoft.PowerShell.Management\Join-Path -Path $env:USERPROFILE -ChildPath "Documents\WindowsPowerShell" } } elseif($script:IsWindows) { $script:MyDocumentsPSPath = Microsoft.PowerShell.Management\Join-Path -Path $HOME -ChildPath 'Documents\PowerShell' } else { $script:MyDocumentsPSPath = Microsoft.PowerShell.Management\Join-Path -Path $HOME -ChildPath ".local/share/powershell" } $script:ProgramFilesModulesPath = Microsoft.PowerShell.Management\Join-Path -Path $script:ProgramFilesPSPath -ChildPath "Modules" $script:MyDocumentsModulesPath = Microsoft.PowerShell.Management\Join-Path -Path $script:MyDocumentsPSPath -ChildPath "Modules" $script:ProgramFilesScriptsPath = Microsoft.PowerShell.Management\Join-Path -Path $script:ProgramFilesPSPath -ChildPath "Scripts" $script:MyDocumentsScriptsPath = Microsoft.PowerShell.Management\Join-Path -Path $script:MyDocumentsPSPath -ChildPath "Scripts" $script:TempPath = if($script:IsWindows){ ([System.IO.DirectoryInfo]$env:TEMP).FullName } else { '/tmp' } $script:PSGetItemInfoFileName = "PSGetModuleInfo.xml" if($script:IsWindows) { $script:PSGetProgramDataPath = Microsoft.PowerShell.Management\Join-Path -Path $env:ProgramData -ChildPath 'Microsoft\Windows\PowerShell\PowerShellGet\' $script:PSGetAppLocalPath = Microsoft.PowerShell.Management\Join-Path -Path $env:LOCALAPPDATA -ChildPath 'Microsoft\Windows\PowerShell\PowerShellGet\' } else { $script:PSGetProgramDataPath = "$HOME/.config/powershell/powershellget" #TODO: Get $env:ProgramData equivalent $script:PSGetAppLocalPath = "$HOME/.config/powershell/powershellget" } $script:PSGetModuleSourcesFilePath = Microsoft.PowerShell.Management\Join-Path -Path $script:PSGetAppLocalPath -ChildPath "PSRepositories.xml" $script:PSGetModuleSources = $null $script:PSGetInstalledModules = $null $script:PSGetSettingsFilePath = Microsoft.PowerShell.Management\Join-Path -Path $script:PSGetAppLocalPath -ChildPath "PowerShellGetSettings.xml" $script:PSGetSettings = $null $script:MyDocumentsInstalledScriptInfosPath = Microsoft.PowerShell.Management\Join-Path -Path $script:MyDocumentsScriptsPath -ChildPath 'InstalledScriptInfos' $script:ProgramFilesInstalledScriptInfosPath = Microsoft.PowerShell.Management\Join-Path -Path $script:ProgramFilesScriptsPath -ChildPath 'InstalledScriptInfos' $script:IsRunningAsElevated = $true $script:IsRunningAsElevatedTested = $false $script:InstalledScriptInfoFileName = 'InstalledScriptInfo.xml' $script:PSGetInstalledScripts = $null # Public PSGallery module source name and location $Script:PSGalleryModuleSource="PSGallery" $Script:PSGallerySourceUri = 'https://go.microsoft.com/fwlink/?LinkID=397631&clcid=0x409' $Script:PSGalleryPublishUri = 'https://go.microsoft.com/fwlink/?LinkID=397527&clcid=0x409' $Script:PSGalleryScriptSourceUri = 'https://go.microsoft.com/fwlink/?LinkID=622995&clcid=0x409' # PSGallery V3 Source $Script:PSGalleryV3SourceUri = 'https://go.microsoft.com/fwlink/?LinkId=528403&clcid=0x409' $Script:PSGalleryV2ApiAvailable = $true $Script:PSGalleryV3ApiAvailable = $false $Script:PSGalleryApiChecked = $false $Script:ResponseUri = "ResponseUri" $Script:StatusCode = "StatusCode" $Script:Exception = "Exception" $script:PSModuleProviderName = 'PowerShellGet' $script:PackageManagementProviderParam = "PackageManagementProvider" $script:PublishLocation = "PublishLocation" $script:ScriptSourceLocation = 'ScriptSourceLocation' $script:ScriptPublishLocation = 'ScriptPublishLocation' $script:Proxy = 'Proxy' $script:ProxyCredential = 'ProxyCredential' $script:Credential = 'Credential' $script:VSTSAuthenticatedFeedsDocUrl = 'https://go.microsoft.com/fwlink/?LinkID=698608' $script:NuGetProviderName = "NuGet" $script:NuGetProviderVersion = [Version]'2.8.5.201' $script:SupportsPSModulesFeatureName="supports-powershell-modules" $script:FastPackRefHashtable = @{} $script:NuGetBinaryProgramDataPath=if($script:IsWindows) {"$env:ProgramFiles\PackageManagement\ProviderAssemblies"} $script:NuGetBinaryLocalAppDataPath=if($script:IsWindows) {"$env:LOCALAPPDATA\PackageManagement\ProviderAssemblies"} # go fwlink for 'https://nuget.org/nuget.exe' $script:NuGetClientSourceURL = 'https://go.microsoft.com/fwlink/?LinkID=690216&clcid=0x409' $script:NuGetExeName = 'NuGet.exe' $script:NuGetExePath = $null $script:NuGetProvider = $null # PowerShellGetFormatVersion will be incremented when we change the .nupkg format structure. # PowerShellGetFormatVersion is in the form of Major.Minor. # Minor is incremented for the backward compatible format change. # Major is incremented for the breaking change. $script:PSGetRequireLicenseAcceptanceFormatVersion = [Version]'2.0' $script:CurrentPSGetFormatVersion = $script:PSGetRequireLicenseAcceptanceFormatVersion $script:PSGetFormatVersion = "PowerShellGetFormatVersion" $script:SupportedPSGetFormatVersionMajors = @("1","2") $script:ModuleReferences = 'Module References' $script:AllVersions = "AllVersions" $script:Filter = "Filter" $script:IncludeValidSet = @('DscResource','Cmdlet','Function','Workflow','RoleCapability') $script:DscResource = "PSDscResource" $script:Command = "PSCommand" $script:Cmdlet = "PSCmdlet" $script:Function = "PSFunction" $script:Workflow = "PSWorkflow" $script:RoleCapability = 'PSRoleCapability' $script:Includes = "PSIncludes" $script:Tag = "Tag" $script:NotSpecified= '_NotSpecified_' $script:PSGetModuleName = 'PowerShellGet' $script:FindByCanonicalId = 'FindByCanonicalId' $script:InstalledLocation = 'InstalledLocation' $script:PSArtifactType = 'Type' $script:PSArtifactTypeModule = 'Module' $script:PSArtifactTypeScript = 'Script' $script:All = 'All' $script:Name = 'Name' $script:Version = 'Version' $script:Guid = 'Guid' $script:Path = 'Path' $script:ScriptBase = 'ScriptBase' $script:Description = 'Description' $script:Author = 'Author' $script:CompanyName = 'CompanyName' $script:Copyright = 'Copyright' $script:Tags = 'Tags' $script:LicenseUri = 'LicenseUri' $script:ProjectUri = 'ProjectUri' $script:IconUri = 'IconUri' $script:RequiredModules = 'RequiredModules' $script:ExternalModuleDependencies = 'ExternalModuleDependencies' $script:ReleaseNotes = 'ReleaseNotes' $script:RequiredScripts = 'RequiredScripts' $script:ExternalScriptDependencies = 'ExternalScriptDependencies' $script:DefinedCommands = 'DefinedCommands' $script:DefinedFunctions = 'DefinedFunctions' $script:DefinedWorkflows = 'DefinedWorkflows' $script:TextInfo = (Get-Culture).TextInfo $script:PrivateData = 'PrivateData' $script:PSScriptInfoProperties = @($script:Name $script:Version, $script:Guid, $script:Path, $script:ScriptBase, $script:Description, $script:Author, $script:CompanyName, $script:Copyright, $script:Tags, $script:ReleaseNotes, $script:RequiredModules, $script:ExternalModuleDependencies, $script:RequiredScripts, $script:ExternalScriptDependencies, $script:LicenseUri, $script:ProjectUri, $script:IconUri, $script:DefinedCommands, $script:DefinedFunctions, $script:DefinedWorkflows, $script:PrivateData ) $script:SystemEnvironmentKey = 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' $script:UserEnvironmentKey = 'HKCU:\Environment' $script:SystemEnvironmentVariableMaximumLength = 1024 $script:UserEnvironmentVariableMaximumLength = 255 $script:EnvironmentVariableTarget = @{ Process = 0; User = 1; Machine = 2 } # Wildcard pattern matching configuration. $script:wildcardOptions = [System.Management.Automation.WildcardOptions]::CultureInvariant -bor ` [System.Management.Automation.WildcardOptions]::IgnoreCase $script:DynamicOptionTypeMap = @{ 0 = [string]; # String 1 = [string[]]; # StringArray 2 = [int]; # Int 3 = [switch]; # Switch 4 = [string]; # Folder 5 = [string]; # File 6 = [string]; # Path 7 = [Uri]; # Uri 8 = [SecureString]; #SecureString } #endregion script variables #region Module message resolvers $script:PackageManagementMessageResolverScriptBlock = { param($i, $Message) return (PackageManagementMessageResolver -MsgId $i, -Message $Message) } $script:PackageManagementSaveModuleMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = $LocalizedData.InstallModulewhatIfMessage $QuerySaveUntrustedPackage = $LocalizedData.QuerySaveUntrustedPackage switch ($i) { 'ActionInstallPackage' { return "Save-Module" } 'QueryInstallUntrustedPackage' {return $QuerySaveUntrustedPackage} 'TargetPackage' { return $PackageTarget } Default { $Message = $Message -creplace "Install", "Download" $Message = $Message -creplace "install", "download" return (PackageManagementMessageResolver -MsgId $i, -Message $Message) } } } $script:PackageManagementInstallModuleMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = $LocalizedData.InstallModulewhatIfMessage switch ($i) { 'ActionInstallPackage' { return "Install-Module" } 'TargetPackage' { return $PackageTarget } Default { return (PackageManagementMessageResolver -MsgId $i, -Message $Message) } } } $script:PackageManagementUnInstallModuleMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = $LocalizedData.InstallModulewhatIfMessage switch ($i) { 'ActionUninstallPackage' { return "Uninstall-Module" } 'TargetPackageVersion' { return $PackageTarget } Default { return (PackageManagementMessageResolver -MsgId $i, -Message $Message) } } } $script:PackageManagementUpdateModuleMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = ($LocalizedData.UpdateModulewhatIfMessage -replace "__OLDVERSION__",$($psgetItemInfo.Version)) switch ($i) { 'ActionInstallPackage' { return "Update-Module" } 'TargetPackage' { return $PackageTarget } Default { return (PackageManagementMessageResolver -MsgId $i, -Message $Message) } } } function PackageManagementMessageResolver($MsgID, $Message) { $NoMatchFound = $LocalizedData.NoMatchFound $SourceNotFound = $LocalizedData.SourceNotFound $ModuleIsNotTrusted = $LocalizedData.ModuleIsNotTrusted $RepositoryIsNotTrusted = $LocalizedData.RepositoryIsNotTrusted $QueryInstallUntrustedPackage = $LocalizedData.QueryInstallUntrustedPackage switch ($MsgID) { 'NoMatchFound' { return $NoMatchFound } 'SourceNotFound' { return $SourceNotFound } 'CaptionPackageNotTrusted' { return $ModuleIsNotTrusted } 'CaptionSourceNotTrusted' { return $RepositoryIsNotTrusted } 'QueryInstallUntrustedPackage' {return $QueryInstallUntrustedPackage} Default { if($Message) { $tempMessage = $Message -creplace "PackageSource", "PSRepository" $tempMessage = $tempMessage -creplace "packagesource", "psrepository" $tempMessage = $tempMessage -creplace "Package", "Module" $tempMessage = $tempMessage -creplace "package", "module" $tempMessage = $tempMessage -creplace "Sources", "Repositories" $tempMessage = $tempMessage -creplace "sources", "repositories" $tempMessage = $tempMessage -creplace "Source", "Repository" $tempMessage = $tempMessage -creplace "source", "repository" return $tempMessage } } } } #endregion Module message resolvers #region Script message resolvers $script:PackageManagementMessageResolverScriptBlockForScriptCmdlets = { param($i, $Message) return (PackageManagementMessageResolverForScripts -MsgId $i, -Message $Message) } $script:PackageManagementSaveScriptMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = $LocalizedData.InstallScriptwhatIfMessage $QuerySaveUntrustedPackage = $LocalizedData.QuerySaveUntrustedScriptPackage switch ($i) { 'ActionInstallPackage' { return "Save-Script" } 'QueryInstallUntrustedPackage' {return $QuerySaveUntrustedPackage} 'TargetPackage' { return $PackageTarget } Default { $Message = $Message -creplace "Install", "Download" $Message = $Message -creplace "install", "download" return (PackageManagementMessageResolverForScripts -MsgId $i, -Message $Message) } } } $script:PackageManagementInstallScriptMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = $LocalizedData.InstallScriptwhatIfMessage switch ($i) { 'ActionInstallPackage' { return "Install-Script" } 'TargetPackage' { return $PackageTarget } Default { return (PackageManagementMessageResolverForScripts -MsgId $i, -Message $Message) } } } $script:PackageManagementUnInstallScriptMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = $LocalizedData.InstallScriptwhatIfMessage switch ($i) { 'ActionUninstallPackage' { return "Uninstall-Script" } 'TargetPackageVersion' { return $PackageTarget } Default { return (PackageManagementMessageResolverForScripts -MsgId $i, -Message $Message) } } } $script:PackageManagementUpdateScriptMessageResolverScriptBlock = { param($i, $Message) $PackageTarget = ($LocalizedData.UpdateScriptwhatIfMessage -replace "__OLDVERSION__",$($psgetItemInfo.Version)) switch ($i) { 'ActionInstallPackage' { return "Update-Script" } 'TargetPackage' { return $PackageTarget } Default { return (PackageManagementMessageResolverForScripts -MsgId $i, -Message $Message) } } } function PackageManagementMessageResolverForScripts($MsgID, $Message) { $NoMatchFound = $LocalizedData.NoMatchFoundForScriptName $SourceNotFound = $LocalizedData.SourceNotFound $ScriptIsNotTrusted = $LocalizedData.ScriptIsNotTrusted $RepositoryIsNotTrusted = $LocalizedData.RepositoryIsNotTrusted $QueryInstallUntrustedPackage = $LocalizedData.QueryInstallUntrustedScriptPackage switch ($MsgID) { 'NoMatchFound' { return $NoMatchFound } 'SourceNotFound' { return $SourceNotFound } 'CaptionPackageNotTrusted' { return $ScriptIsNotTrusted } 'CaptionSourceNotTrusted' { return $RepositoryIsNotTrusted } 'QueryInstallUntrustedPackage' {return $QueryInstallUntrustedPackage} Default { if($Message) { $tempMessage = $Message -creplace "PackageSource", "PSRepository" $tempMessage = $tempMessage -creplace "packagesource", "psrepository" $tempMessage = $tempMessage -creplace "Package", "Script" $tempMessage = $tempMessage -creplace "package", "script" $tempMessage = $tempMessage -creplace "Sources", "Repositories" $tempMessage = $tempMessage -creplace "sources", "repositories" $tempMessage = $tempMessage -creplace "Source", "Repository" $tempMessage = $tempMessage -creplace "source", "repository" return $tempMessage } } } } #endregion Script message resolvers Microsoft.PowerShell.Utility\Import-LocalizedData LocalizedData -filename PSGet.Resource.psd1 #region Add .Net type for Telemetry APIs and WebProxy # Check and add InternalWebProxy type if( -not ('Microsoft.PowerShell.Commands.PowerShellGet.InternalWebProxy' -as [Type])) { $RequiredAssembliesForInternalWebProxy = @( [System.Net.IWebProxy].Assembly.FullName, [System.Uri].Assembly.FullName ) $InternalWebProxySource = @' using System; using System.Net; namespace Microsoft.PowerShell.Commands.PowerShellGet { /// <summary> /// Used by Ping-Endpoint function to supply webproxy to HttpClient /// We cannot use System.Net.WebProxy because this is not available on CoreClr /// </summary> public class InternalWebProxy : IWebProxy { Uri _proxyUri; ICredentials _credentials; public InternalWebProxy(Uri uri, ICredentials credentials) { Credentials = credentials; _proxyUri = uri; } /// <summary> /// Credentials used by WebProxy /// </summary> public ICredentials Credentials { get { return _credentials; } set { _credentials = value; } } public Uri GetProxy(Uri destination) { return _proxyUri; } public bool IsBypassed(Uri host) { return false; } } } '@ try { $AddType_prams = @{ TypeDefinition = $InternalWebProxySource Language = 'CSharp' ErrorAction = 'SilentlyContinue' } if (-not $script:IsCoreCLR) { $AddType_prams['ReferencedAssemblies'] = $RequiredAssembliesForInternalWebProxy } Add-Type @AddType_prams } catch { Write-Warning -Message "InternalWebProxy: $_" } } # Check and add Telemetry type if(('Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI' -as [Type]) -and -not ('Microsoft.PowerShell.Commands.PowerShellGet.Telemetry' -as [Type])) { $RequiredAssembliesForTelemetry = @( [System.Management.Automation.PSCmdlet].Assembly.FullName ) $TelemetrySource = @' using System; using System.Management.Automation; namespace Microsoft.PowerShell.Commands.PowerShellGet { public static class Telemetry { public static void TraceMessageArtifactsNotFound(string[] artifactsNotFound, string operationName) { Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI.TraceMessage(operationName, new { ArtifactsNotFound = artifactsNotFound }); } public static void TraceMessageNonPSGalleryRegistration(string sourceLocationType, string sourceLocationHash, string installationPolicy, string packageManagementProvider, string publishLocationHash, string scriptSourceLocationHash, string scriptPublishLocationHash, string operationName) { Microsoft.PowerShell.Telemetry.Internal.TelemetryAPI.TraceMessage(operationName, new { SourceLocationType = sourceLocationType, SourceLocationHash = sourceLocationHash, InstallationPolicy = installationPolicy, PackageManagementProvider = packageManagementProvider, PublishLocationHash = publishLocationHash, ScriptSourceLocationHash = scriptSourceLocationHash, ScriptPublishLocationHash = scriptPublishLocationHash }); } } } '@ try { $AddType_prams = @{ TypeDefinition = $TelemetrySource Language = 'CSharp' ErrorAction = 'SilentlyContinue' } $AddType_prams['ReferencedAssemblies'] = $RequiredAssembliesForTelemetry Add-Type @AddType_prams } catch { Write-Warning -Message "Telemetry: $_" } } # Turn ON Telemetry if the infrastructure is present on the machine $script:TelemetryEnabled = $false if('Microsoft.PowerShell.Commands.PowerShellGet.Telemetry' -as [Type]) { $telemetryMethods = ([Microsoft.PowerShell.Commands.PowerShellGet.Telemetry] | Get-Member -Static).Name if ($telemetryMethods.Contains("TraceMessageArtifactsNotFound") -and $telemetryMethods.Contains("TraceMessageNonPSGalleryRegistration")) { $script:TelemetryEnabled = $true } } # Check and add Win32Helpers type $script:IsSafeX509ChainHandleAvailable = ($null -ne ('Microsoft.Win32.SafeHandles.SafeX509ChainHandle' -as [Type])) if($script:IsWindows -and -not ('Microsoft.PowerShell.Commands.PowerShellGet.Win32Helpers' -as [Type])) { $RequiredAssembliesForWin32Helpers = @() if($script:IsSafeX509ChainHandleAvailable) { # It is not possible to define a single internal SafeHandle class in PowerShellGet namespace for all the supported versions of .Net Framework including .Net Core. # SafeHandleZeroOrMinusOneIsInvalid is not a public class on .Net Core, # therefore SafeX509ChainHandle will be used if it is available otherwise InternalSafeX509ChainHandle is defined below. # # ChainContext is not available on .Net Core, we must have to use SafeX509ChainHandle on .Net Core. # $SafeX509ChainHandleClassName = 'SafeX509ChainHandle' $RequiredAssembliesForWin32Helpers += [Microsoft.Win32.SafeHandles.SafeX509ChainHandle].Assembly.FullName } else { # SafeX509ChainHandle is not available on .Net Framework 4.5 or older versions, # therefore InternalSafeX509ChainHandle is defined below. # $SafeX509ChainHandleClassName = 'InternalSafeX509ChainHandle' } $Win32HelpersSource = @" using System; using System.Net; using Microsoft.Win32.SafeHandles; using System.Security.Cryptography; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Runtime.Versioning; using System.Security; namespace Microsoft.PowerShell.Commands.PowerShellGet { [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct CERT_CHAIN_POLICY_PARA { public CERT_CHAIN_POLICY_PARA(int size) { cbSize = (uint) size; dwFlags = 0; pvExtraPolicyPara = IntPtr.Zero; } public uint cbSize; public uint dwFlags; public IntPtr pvExtraPolicyPara; } [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct CERT_CHAIN_POLICY_STATUS { public CERT_CHAIN_POLICY_STATUS(int size) { cbSize = (uint) size; dwError = 0; lChainIndex = IntPtr.Zero; lElementIndex = IntPtr.Zero; pvExtraPolicyStatus = IntPtr.Zero; } public uint cbSize; public uint dwError; public IntPtr lChainIndex; public IntPtr lElementIndex; public IntPtr pvExtraPolicyStatus; } // Internal SafeHandleZeroOrMinusOneIsInvalid class to remove the dependency on .Net Framework 4.6. public abstract class InternalSafeHandleZeroOrMinusOneIsInvalid : SafeHandle { protected InternalSafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle) { } public override bool IsInvalid { get { return handle == IntPtr.Zero || handle == new IntPtr(-1); } } } // Internal SafeX509ChainHandle class to remove the dependency on .Net Framework 4.6. [SecurityCritical] public sealed class InternalSafeX509ChainHandle : InternalSafeHandleZeroOrMinusOneIsInvalid { private InternalSafeX509ChainHandle () : base(true) {} internal InternalSafeX509ChainHandle (IntPtr handle) : base (true) { SetHandle(handle); } internal static InternalSafeX509ChainHandle InvalidHandle { get { return new InternalSafeX509ChainHandle(IntPtr.Zero); } } [SecurityCritical] override protected bool ReleaseHandle() { CertFreeCertificateChain(handle); return true; } [DllImport("Crypt32.dll", SetLastError=true)] $(if(-not $script:isNanoServer) { ' [SuppressUnmanagedCodeSecurity, ResourceExposure(ResourceScope.None), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] ' }) private static extern void CertFreeCertificateChain(IntPtr handle); } public class Win32Helpers { [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] public extern static bool CertVerifyCertificateChainPolicy( [In] IntPtr pszPolicyOID, [In] $SafeX509ChainHandleClassName pChainContext, [In] ref CERT_CHAIN_POLICY_PARA pPolicyPara, [In,Out] ref CERT_CHAIN_POLICY_STATUS pPolicyStatus); [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern $SafeX509ChainHandleClassName CertDuplicateCertificateChain( [In] IntPtr pChainContext); $(if($script:IsSafeX509ChainHandleAvailable) { @" [DllImport("Crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] $(if(-not $script:isNanoServer) { ' [ResourceExposure(ResourceScope.None)] ' }) public static extern SafeX509ChainHandle CertDuplicateCertificateChain( [In] SafeX509ChainHandle pChainContext); "@ }) public static bool IsMicrosoftCertificate([In] $SafeX509ChainHandleClassName pChainContext) { //------------------------------------------------------------------------- // CERT_CHAIN_POLICY_MICROSOFT_ROOT // // Checks if the last element of the first simple chain contains a // Microsoft root public key. If it doesn't contain a Microsoft root // public key, dwError is set to CERT_E_UNTRUSTEDROOT. // // pPolicyPara is optional. However, // MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG can be set in // the dwFlags in pPolicyPara to also check for the Microsoft Test Roots. // // MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG can be set // in the dwFlags in pPolicyPara to check for the Microsoft root for // application signing instead of the Microsoft product root. This flag // explicitly checks for the application root only and cannot be combined // with the test root flag. // // MICROSOFT_ROOT_CERT_CHAIN_POLICY_DISABLE_FLIGHT_ROOT_FLAG can be set // in the dwFlags in pPolicyPara to always disable the Flight root. // // pvExtraPolicyPara and pvExtraPolicyStatus aren't used and must be set // to NULL. //-------------------------------------------------------------------------- const uint MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG = 0x00010000; const uint MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG = 0x00020000; //const uint MICROSOFT_ROOT_CERT_CHAIN_POLICY_DISABLE_FLIGHT_ROOT_FLAG = 0x00040000; CERT_CHAIN_POLICY_PARA PolicyPara = new CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_PARA))); CERT_CHAIN_POLICY_STATUS PolicyStatus = new CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_STATUS))); int CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7; PolicyPara.dwFlags = (uint) MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG; bool isMicrosoftRoot = false; if(CertVerifyCertificateChainPolicy(new IntPtr(CERT_CHAIN_POLICY_MICROSOFT_ROOT), pChainContext, ref PolicyPara, ref PolicyStatus)) { isMicrosoftRoot = (PolicyStatus.dwError == 0); } // Also check for the Microsoft root for application signing if the Microsoft product root verification is unsuccessful. if(!isMicrosoftRoot) { // Some Microsoft modules can be signed with Microsoft Application Root instead of Microsoft Product Root, // So we need to use the MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG for the certificate verification. // MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG can not be used // with MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG, // so additional CertVerifyCertificateChainPolicy call is required to verify the given certificate is in Microsoft Application Root. // CERT_CHAIN_POLICY_PARA PolicyPara2 = new CERT_CHAIN_POLICY_PARA(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_PARA))); CERT_CHAIN_POLICY_STATUS PolicyStatus2 = new CERT_CHAIN_POLICY_STATUS(Marshal.SizeOf(typeof(CERT_CHAIN_POLICY_STATUS))); PolicyPara2.dwFlags = (uint) MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG; if(CertVerifyCertificateChainPolicy(new IntPtr(CERT_CHAIN_POLICY_MICROSOFT_ROOT), pChainContext, ref PolicyPara2, ref PolicyStatus2)) { isMicrosoftRoot = (PolicyStatus2.dwError == 0); } } return isMicrosoftRoot; } } } "@ try { $AddType_prams = @{ TypeDefinition = $Win32HelpersSource Language = 'CSharp' ErrorAction = 'SilentlyContinue' } if (-not $script:IsCoreCLR -and $RequiredAssembliesForWin32Helpers) { $AddType_prams['ReferencedAssemblies'] = $RequiredAssembliesForWin32Helpers } Add-Type @AddType_prams } catch { Write-Warning -Message "Win32Helpers: $_" } } #endregion #region *-Module cmdlets function Publish-Module { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(SupportsShouldProcess=$true, PositionalBinding=$false, HelpUri='https://go.microsoft.com/fwlink/?LinkID=398575', DefaultParameterSetName="ModuleNameParameterSet")] Param ( [Parameter(Mandatory=$true, ParameterSetName="ModuleNameParameterSet", ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory=$true, ParameterSetName="ModulePathParameterSet", ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter(ParameterSetName="ModuleNameParameterSet")] [ValidateNotNullOrEmpty()] [Version] $RequiredVersion, [Parameter()] [ValidateNotNullOrEmpty()] [string] $NuGetApiKey, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Repository = $Script:PSGalleryModuleSource, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter()] [ValidateSet("2.0")] [Version] $FormatVersion, [Parameter()] [string[]] $ReleaseNotes, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Tags, [Parameter()] [ValidateNotNullOrEmpty()] [Uri] $LicenseUri, [Parameter()] [ValidateNotNullOrEmpty()] [Uri] $IconUri, [Parameter()] [ValidateNotNullOrEmpty()] [Uri] $ProjectUri, [Parameter()] [switch] $Force ) Begin { if($script:isNanoServer -or $script:IsCoreCLR) { $message = $LocalizedData.PublishPSArtifactUnsupportedOnNano -f "Module" ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId 'PublishModuleIsNotSupportedOnPowerShellCoreEdition' ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $PSCmdlet ` -ErrorCategory InvalidOperation } Get-PSGalleryApiAvailability -Repository $Repository if($LicenseUri -and -not (Test-WebUri -uri $LicenseUri)) { $message = $LocalizedData.InvalidWebUri -f ($LicenseUri, "LicenseUri") ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "InvalidWebUri" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $LicenseUri } if($IconUri -and -not (Test-WebUri -uri $IconUri)) { $message = $LocalizedData.InvalidWebUri -f ($IconUri, "IconUri") ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "InvalidWebUri" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $IconUri } if($ProjectUri -and -not (Test-WebUri -uri $ProjectUri)) { $message = $LocalizedData.InvalidWebUri -f ($ProjectUri, "ProjectUri") ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "InvalidWebUri" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $ProjectUri } Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -BootstrapNuGetExe -Force:$Force } Process { if($Repository -eq $Script:PSGalleryModuleSource) { $moduleSource = Get-PSRepository -Name $Repository -ErrorAction SilentlyContinue -WarningAction SilentlyContinue if(-not $moduleSource) { $message = $LocalizedData.PSGalleryNotFound -f ($Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId 'PSGalleryNotFound' ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Repository return } } else { $ev = $null $moduleSource = Get-PSRepository -Name $Repository -ErrorVariable ev if($ev) { return } } $DestinationLocation = $moduleSource.PublishLocation if(-not $DestinationLocation -or (-not (Microsoft.PowerShell.Management\Test-Path $DestinationLocation) -and -not (Test-WebUri -uri $DestinationLocation))) { $message = $LocalizedData.PSGalleryPublishLocationIsMissing -f ($Repository, $Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "PSGalleryPublishLocationIsMissing" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Repository } $message = $LocalizedData.PublishLocation -f ($DestinationLocation) Write-Verbose -Message $message if(-not $NuGetApiKey.Trim()) { if(Microsoft.PowerShell.Management\Test-Path -Path $DestinationLocation) { $NuGetApiKey = "$(Get-Random)" } else { $message = $LocalizedData.NuGetApiKeyIsRequiredForNuGetBasedGalleryService -f ($Repository, $DestinationLocation) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "NuGetApiKeyIsRequiredForNuGetBasedGalleryService" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument } } $providerName = Get-ProviderName -PSCustomObject $moduleSource if($providerName -ne $script:NuGetProviderName) { $message = $LocalizedData.PublishModuleSupportsOnlyNuGetBasedPublishLocations -f ($moduleSource.PublishLocation, $Repository, $Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "PublishModuleSupportsOnlyNuGetBasedPublishLocations" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Repository } $moduleName = $null if($Name) { $module = Microsoft.PowerShell.Core\Get-Module -ListAvailable -Name $Name -Verbose:$false | Microsoft.PowerShell.Core\Where-Object {-not $RequiredVersion -or ($RequiredVersion -eq $_.Version)} if(-not $module) { if($RequiredVersion) { $message = $LocalizedData.ModuleWithRequiredVersionNotAvailableLocally -f ($Name, $RequiredVersion) } else { $message = $LocalizedData.ModuleNotAvailableLocally -f ($Name) } ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "ModuleNotAvailableLocallyToPublish" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Name } elseif($module.GetType().ToString() -ne "System.Management.Automation.PSModuleInfo") { $message = $LocalizedData.AmbiguousModuleName -f ($Name) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "AmbiguousModuleNameToPublish" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Name } $moduleName = $module.Name $Path = $module.ModuleBase } else { $resolvedPath = Resolve-PathHelper -Path $Path -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $resolvedPath -or -not (Microsoft.PowerShell.Management\Test-Path -Path $resolvedPath -PathType Container)) { ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage ($LocalizedData.PathIsNotADirectory -f ($Path)) ` -ErrorId "PathIsNotADirectory" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Path return } $moduleName = Microsoft.PowerShell.Management\Split-Path -Path $resolvedPath -Leaf $modulePathWithVersion = $false # if the Leaf of the $resolvedPath is a version, use its parent folder name as the module name $ModuleVersion = New-Object System.Version if([System.Version]::TryParse($moduleName, ([ref]$ModuleVersion))) { $moduleName = Microsoft.PowerShell.Management\Split-Path -Path (Microsoft.PowerShell.Management\Split-Path $resolvedPath -Parent) -Leaf $modulePathWithVersion = $true } $manifestPath = Join-Path -Path $resolvedPath -ChildPath "$moduleName.psd1" $module = $null if(Microsoft.PowerShell.Management\Test-Path -Path $manifestPath -PathType Leaf) { $ev = $null $module = Microsoft.PowerShell.Core\Test-ModuleManifest -Path $manifestPath ` -ErrorVariable ev ` -Verbose:$VerbosePreference if($ev) { # Above Test-ModuleManifest cmdlet should write an errors to the Errors stream and Console. return } } elseif(-not $modulePathWithVersion -and ($PSVersionTable.PSVersion -ge '5.0.0')) { $module = Microsoft.PowerShell.Core\Get-Module -Name $resolvedPath -ListAvailable -ErrorAction SilentlyContinue -Verbose:$false } if(-not $module) { $message = $LocalizedData.InvalidModulePathToPublish -f ($Path) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId 'InvalidModulePathToPublish' ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Path } elseif($module.GetType().ToString() -ne "System.Management.Automation.PSModuleInfo") { $message = $LocalizedData.AmbiguousModulePath -f ($Path) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId 'AmbiguousModulePathToPublish' ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Path } if($module -and (-not $module.Path.EndsWith('.psd1', [System.StringComparison]::OrdinalIgnoreCase))) { $message = $LocalizedData.InvalidModuleToPublish -f ($module.Name) ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "InvalidModuleToPublish" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation ` -ExceptionObject $module.Name } $moduleName = $module.Name $Path = $module.ModuleBase } $message = $LocalizedData.PublishModuleLocation -f ($moduleName, $Path) Write-Verbose -Message $message #If users are providing tags using -Tags while running PS 5.0, will show warning messages if($Tags) { $message = $LocalizedData.TagsShouldBeIncludedInManifestFile -f ($moduleName, $Path) Write-Warning $message } if($ReleaseNotes) { $message = $LocalizedData.ReleaseNotesShouldBeIncludedInManifestFile -f ($moduleName, $Path) Write-Warning $message } if($LicenseUri) { $message = $LocalizedData.LicenseUriShouldBeIncludedInManifestFile -f ($moduleName, $Path) Write-Warning $message } if($IconUri) { $message = $LocalizedData.IconUriShouldBeIncludedInManifestFile -f ($moduleName, $Path) Write-Warning $message } if($ProjectUri) { $message = $LocalizedData.ProjectUriShouldBeIncludedInManifestFile -f ($moduleName, $Path) Write-Warning $message } # Copy the source module to temp location to publish $tempModulePath = Microsoft.PowerShell.Management\Join-Path -Path $script:TempPath ` -ChildPath "$(Microsoft.PowerShell.Utility\Get-Random)\$moduleName" if ($FormatVersion -eq "1.0") { $tempModulePathForFormatVersion = Microsoft.PowerShell.Management\Join-Path $tempModulePath "Content\Deployment\$script:ModuleReferences\$moduleName" } else { $tempModulePathForFormatVersion = $tempModulePath } $null = Microsoft.PowerShell.Management\New-Item -Path $tempModulePathForFormatVersion -ItemType Directory -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false Microsoft.PowerShell.Management\Copy-Item -Path "$Path\*" -Destination $tempModulePathForFormatVersion -Force -Recurse -Confirm:$false -WhatIf:$false try { $manifestPath = Microsoft.PowerShell.Management\Join-Path $tempModulePathForFormatVersion "$moduleName.psd1" if(-not (Microsoft.PowerShell.Management\Test-Path $manifestPath)) { $message = $LocalizedData.InvalidModuleToPublish -f ($moduleName) ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "InvalidModuleToPublish" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation ` -ExceptionObject $moduleName } $ev = $null $moduleInfo = Microsoft.PowerShell.Core\Test-ModuleManifest -Path $manifestPath ` -ErrorVariable ev ` -Verbose:$VerbosePreference if($ev) { # Above Test-ModuleManifest cmdlet should write an errors to the Errors stream and Console. return } if(-not $moduleInfo -or -not $moduleInfo.Author -or -not $moduleInfo.Description) { $message = $LocalizedData.MissingRequiredManifestKeys -f ($moduleName) ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "MissingRequiredModuleManifestKeys" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation ` -ExceptionObject $moduleName } $FindParameters = @{ Name = $moduleName Repository = $Repository Tag = 'PSScript' Verbose = $VerbosePreference ErrorAction = 'SilentlyContinue' WarningAction = 'SilentlyContinue' Debug = $DebugPreference } if($Credential) { $FindParameters[$script:Credential] = $Credential } # Check if the specified module name is already used for a script on the specified repository # Use Find-Script to check if that name is already used as scriptname $scriptPSGetItemInfo = Find-Script @FindParameters | Microsoft.PowerShell.Core\Where-Object {$_.Name -eq $moduleName} | Microsoft.PowerShell.Utility\Select-Object -Last 1 -ErrorAction Ignore if($scriptPSGetItemInfo) { $message = $LocalizedData.SpecifiedNameIsAlearyUsed -f ($moduleName, $Repository, 'Find-Script') ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "SpecifiedNameIsAlearyUsed" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation ` -ExceptionObject $moduleName } $null = $FindParameters.Remove('Tag') $currentPSGetItemInfo = Find-Module @FindParameters | Microsoft.PowerShell.Core\Where-Object {$_.Name -eq $moduleInfo.Name} | Microsoft.PowerShell.Utility\Select-Object -Last 1 -ErrorAction Ignore if($currentPSGetItemInfo) { if($currentPSGetItemInfo.Version -eq $moduleInfo.Version) { $message = $LocalizedData.ModuleVersionIsAlreadyAvailableInTheGallery -f ($moduleInfo.Name, $moduleInfo.Version, $currentPSGetItemInfo.Version, $currentPSGetItemInfo.RepositorySourceLocation) ThrowError -ExceptionName 'System.InvalidOperationException' ` -ExceptionMessage $message ` -ErrorId 'ModuleVersionIsAlreadyAvailableInTheGallery' ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation } elseif(-not $Force -and ($currentPSGetItemInfo.Version -gt $moduleInfo.Version)) { $message = $LocalizedData.ModuleVersionShouldBeGreaterThanGalleryVersion -f ($moduleInfo.Name, $moduleInfo.Version, $currentPSGetItemInfo.Version, $currentPSGetItemInfo.RepositorySourceLocation) ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "ModuleVersionShouldBeGreaterThanGalleryVersion" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation } } $shouldProcessMessage = $LocalizedData.PublishModulewhatIfMessage -f ($moduleInfo.Version, $moduleInfo.Name) if($Force -or $PSCmdlet.ShouldProcess($shouldProcessMessage, "Publish-Module")) { $PublishPSArtifactUtility_Params = @{ PSModuleInfo=$moduleInfo ManifestPath=$manifestPath NugetApiKey=$NuGetApiKey Destination=$DestinationLocation Repository=$Repository NugetPackageRoot=$tempModulePath FormatVersion=$FormatVersion ReleaseNotes=$($ReleaseNotes -join "`r`n") Tags=$Tags LicenseUri=$LicenseUri IconUri=$IconUri ProjectUri=$ProjectUri Verbose=$VerbosePreference WarningAction=$WarningPreference ErrorAction=$ErrorActionPreference Debug=$DebugPreference } if ($PSBoundParameters.Containskey('Credential')) { $PublishPSArtifactUtility_Params.Add('Credential',$Credential) } Publish-PSArtifactUtility @PublishPSArtifactUtility_Params } } finally { Microsoft.PowerShell.Management\Remove-Item $tempModulePath -Force -Recurse -ErrorAction Ignore -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } } } function Find-Module { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(HelpUri='https://go.microsoft.com/fwlink/?LinkID=398574')] [outputtype("PSCustomObject[]")] Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter()] [switch] $AllVersions, [Parameter()] [switch] $IncludeDependencies, [Parameter()] [ValidateNotNull()] [string] $Filter, [Parameter()] [ValidateNotNull()] [string[]] $Tag, [Parameter()] [ValidateNotNull()] [ValidateSet('DscResource','Cmdlet','Function','RoleCapability')] [string[]] $Includes, [Parameter()] [ValidateNotNull()] [string[]] $DscResource, [Parameter()] [ValidateNotNull()] [string[]] $RoleCapability, [Parameter()] [ValidateNotNull()] [string[]] $Command, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Repository, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential ) Begin { Get-PSGalleryApiAvailability -Repository $Repository Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential } Process { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion ` -AllVersions:$AllVersions if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule if($PSBoundParameters.ContainsKey("Repository")) { $PSBoundParameters["Source"] = $Repository $null = $PSBoundParameters.Remove("Repository") $ev = $null $null = Get-PSRepository -Name $Repository -ErrorVariable ev -verbose:$false if($ev) { return } } $PSBoundParameters["MessageResolver"] = $script:PackageManagementMessageResolverScriptBlock $modulesFoundInPSGallery = @() # No Telemetry must be performed if PSGallery is not in the supplied list of Repositories $isRepositoryNullOrPSGallerySpecified = $false if ($Repository -and ($Repository -Contains $Script:PSGalleryModuleSource)) { $isRepositoryNullOrPSGallerySpecified = $true } elseif(-not $Repository) { $psgalleryRepo = Get-PSRepository -Name $Script:PSGalleryModuleSource ` -ErrorAction SilentlyContinue ` -WarningAction SilentlyContinue if($psgalleryRepo) { $isRepositoryNullOrPSGallerySpecified = $true } } PackageManagement\Find-Package @PSBoundParameters | Microsoft.PowerShell.Core\ForEach-Object { $psgetItemInfo = New-PSGetItemInfo -SoftwareIdentity $_ -Type $script:PSArtifactTypeModule $psgetItemInfo if ($psgetItemInfo -and $isRepositoryNullOrPSGallerySpecified -and $script:TelemetryEnabled -and ($psgetItemInfo.Repository -eq $Script:PSGalleryModuleSource)) { $modulesFoundInPSGallery += $psgetItemInfo.Name } } # Perform Telemetry if Repository is not supplied or Repository contains PSGallery # We are only interested in finding modules not in PSGallery if ($isRepositoryNullOrPSGallerySpecified) { Log-ArtifactNotFoundInPSGallery -SearchedName $Name -FoundName $modulesFoundInPSGallery -operationName 'PSGET_FIND_MODULE' } } } function Save-Module { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(DefaultParameterSetName='NameAndPathParameterSet', HelpUri='https://go.microsoft.com/fwlink/?LinkId=531351', SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='NameAndPathParameterSet')] [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputOjectAndPathParameterSet')] [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputOjectAndLiteralPathParameterSet')] [ValidateNotNull()] [PSCustomObject[]] $InputObject, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Repository, [Parameter(Mandatory=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(Mandatory=$true, ParameterSetName='InputOjectAndPathParameterSet')] [string] $Path, [Parameter(Mandatory=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [Parameter(Mandatory=$true, ParameterSetName='InputOjectAndLiteralPathParameterSet')] [string] $LiteralPath, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter()] [switch] $Force, [Parameter()] [switch] $AcceptLicense ) Begin { Get-PSGalleryApiAvailability -Repository $Repository Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential # Module names already tried in the current pipeline for InputObject parameterset $moduleNamesInPipeline = @() } Process { $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters["MessageResolver"] = $script:PackageManagementSaveModuleMessageResolverScriptBlock $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule # When -Force is specified, Path will be created if not available. if(-not $Force) { if($Path) { $destinationPath = Resolve-PathHelper -Path $Path -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $destinationPath -or -not (Microsoft.PowerShell.Management\Test-path $destinationPath)) { $errorMessage = ($LocalizedData.PathNotFound -f $Path) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "PathNotFound" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $Path ` -ErrorCategory InvalidArgument } $PSBoundParameters['Path'] = $destinationPath } else { $destinationPath = Resolve-PathHelper -Path $LiteralPath -IsLiteralPath -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $destinationPath -or -not (Microsoft.PowerShell.Management\Test-Path -LiteralPath $destinationPath)) { $errorMessage = ($LocalizedData.PathNotFound -f $LiteralPath) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "PathNotFound" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $LiteralPath ` -ErrorCategory InvalidArgument } $PSBoundParameters['LiteralPath'] = $destinationPath } } if($Name) { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -TestWildcardsInName ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } if($PSBoundParameters.ContainsKey("Repository")) { $PSBoundParameters["Source"] = $Repository $null = $PSBoundParameters.Remove("Repository") $ev = $null $null = Get-PSRepository -Name $Repository -ErrorVariable ev -verbose:$false if($ev) { return } } $null = PackageManagement\Save-Package @PSBoundParameters } elseif($InputObject) { $null = $PSBoundParameters.Remove("InputObject") foreach($inputValue in $InputObject) { if (($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSGetCommandInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSGetCommandInfo") -and ($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -and ($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo")) { ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $LocalizedData.InvalidInputObjectValue ` -ErrorId "InvalidInputObjectValue" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $inputValue } if( ($inputValue.PSTypeNames -contains "Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -or ($inputValue.PSTypeNames -contains "Deserialized.Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -or ($inputValue.PSTypeNames -contains "Microsoft.PowerShell.Commands.PSGetCommandInfo") -or ($inputValue.PSTypeNames -contains "Deserialized.Microsoft.PowerShell.Commands.PSGetCommandInfo") -or ($inputValue.PSTypeNames -contains "Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo") -or ($inputValue.PSTypeNames -contains "Deserialized.Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo")) { $psgetModuleInfo = $inputValue.PSGetModuleInfo } else { $psgetModuleInfo = $inputValue } # Skip the module name if it is already tried in the current pipeline if($moduleNamesInPipeline -contains $psgetModuleInfo.Name) { continue } $moduleNamesInPipeline += $psgetModuleInfo.Name if ($psgetModuleInfo.PowerShellGetFormatVersion -and ($script:SupportedPSGetFormatVersionMajors -notcontains $psgetModuleInfo.PowerShellGetFormatVersion.Major)) { $message = $LocalizedData.NotSupportedPowerShellGetFormatVersion -f ($psgetModuleInfo.Name, $psgetModuleInfo.PowerShellGetFormatVersion, $psgetModuleInfo.Name) Write-Error -Message $message -ErrorId "NotSupportedPowerShellGetFormatVersion" -Category InvalidOperation continue } $PSBoundParameters["Name"] = $psgetModuleInfo.Name $PSBoundParameters["RequiredVersion"] = $psgetModuleInfo.Version $PSBoundParameters['Source'] = $psgetModuleInfo.Repository $PSBoundParameters["PackageManagementProvider"] = (Get-ProviderName -PSCustomObject $psgetModuleInfo) $null = PackageManagement\Save-Package @PSBoundParameters } } } } function Install-Module { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(DefaultParameterSetName='NameParameterSet', HelpUri='https://go.microsoft.com/fwlink/?LinkID=398573', SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='NameParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputObject')] [ValidateNotNull()] [PSCustomObject[]] $InputObject, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ParameterSetName='NameParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Repository, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter()] [ValidateSet("CurrentUser","AllUsers")] [string] $Scope = "AllUsers", [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [switch] $AllowClobber, [Parameter()] [switch] $SkipPublisherCheck, [Parameter()] [switch] $Force, [Parameter()] [switch] $AcceptLicense ) Begin { Get-PSGalleryApiAvailability -Repository $Repository if(-not (Test-RunningAsElevated) -and ($Scope -ne "CurrentUser")) { # Throw an error when Install-Module is used as a non-admin user and '-Scope CurrentUser' is not specified $message = $LocalizedData.InstallModuleNeedsCurrentUserScopeParameterForNonAdminUser -f @($script:programFilesModulesPath, $script:MyDocumentsModulesPath) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "InstallModuleNeedsCurrentUserScopeParameterForNonAdminUser" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument } Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential # Module names already tried in the current pipeline for InputObject parameterset $moduleNamesInPipeline = @() $YesToAll = $false $NoToAll = $false $SourceSGrantedTrust = @() $SourcesDeniedTrust = @() } Process { $RepositoryIsNotTrusted = $LocalizedData.RepositoryIsNotTrusted $QueryInstallUntrustedPackage = $LocalizedData.QueryInstallUntrustedPackage $PackageTarget = $LocalizedData.InstallModulewhatIfMessage $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters["MessageResolver"] = $script:PackageManagementInstallModuleMessageResolverScriptBlock $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule $PSBoundParameters['Scope'] = $Scope if($PSCmdlet.ParameterSetName -eq "NameParameterSet") { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -TestWildcardsInName ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } if($PSBoundParameters.ContainsKey("Repository")) { $PSBoundParameters["Source"] = $Repository $null = $PSBoundParameters.Remove("Repository") $ev = $null $null = Get-PSRepository -Name $Repository -ErrorVariable ev -verbose:$false if($ev) { return } } $null = PackageManagement\Install-Package @PSBoundParameters } elseif($PSCmdlet.ParameterSetName -eq "InputObject") { $null = $PSBoundParameters.Remove("InputObject") foreach($inputValue in $InputObject) { if (($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSGetCommandInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSGetCommandInfo") -and ($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -and ($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo")) { ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $LocalizedData.InvalidInputObjectValue ` -ErrorId "InvalidInputObjectValue" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $inputValue } if( ($inputValue.PSTypeNames -contains "Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -or ($inputValue.PSTypeNames -contains "Deserialized.Microsoft.PowerShell.Commands.PSGetDscResourceInfo") -or ($inputValue.PSTypeNames -contains "Microsoft.PowerShell.Commands.PSGetCommandInfo") -or ($inputValue.PSTypeNames -contains "Deserialized.Microsoft.PowerShell.Commands.PSGetCommandInfo") -or ($inputValue.PSTypeNames -contains "Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo") -or ($inputValue.PSTypeNames -contains "Deserialized.Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo")) { $psgetModuleInfo = $inputValue.PSGetModuleInfo } else { $psgetModuleInfo = $inputValue } # Skip the module name if it is already tried in the current pipeline if($moduleNamesInPipeline -contains $psgetModuleInfo.Name) { continue } $moduleNamesInPipeline += $psgetModuleInfo.Name if ($psgetModuleInfo.PowerShellGetFormatVersion -and ($script:SupportedPSGetFormatVersionMajors -notcontains $psgetModuleInfo.PowerShellGetFormatVersion.Major)) { $message = $LocalizedData.NotSupportedPowerShellGetFormatVersion -f ($psgetModuleInfo.Name, $psgetModuleInfo.PowerShellGetFormatVersion, $psgetModuleInfo.Name) Write-Error -Message $message -ErrorId "NotSupportedPowerShellGetFormatVersion" -Category InvalidOperation continue } $PSBoundParameters["Name"] = $psgetModuleInfo.Name $PSBoundParameters["RequiredVersion"] = $psgetModuleInfo.Version $PSBoundParameters['Source'] = $psgetModuleInfo.Repository $PSBoundParameters["PackageManagementProvider"] = (Get-ProviderName -PSCustomObject $psgetModuleInfo) #Check if module is already installed $InstalledModuleInfo = Test-ModuleInstalled -Name $psgetModuleInfo.Name -RequiredVersion $psgetModuleInfo.Version if(-not $Force -and $InstalledModuleInfo -ne $null) { $message = $LocalizedData.ModuleAlreadyInstalledVerbose -f ($InstalledModuleInfo.Version, $InstalledModuleInfo.Name, $InstalledModuleInfo.ModuleBase) Write-Verbose -Message $message } else { $source = $psgetModuleInfo.Repository $installationPolicy = (Get-PSRepository -Name $source).InstallationPolicy $ShouldProcessMessage = $PackageTarget -f ($psgetModuleInfo.Name, $psgetModuleInfo.Version) if($psCmdlet.ShouldProcess($ShouldProcessMessage)) { if($installationPolicy.Equals("Untrusted", [StringComparison]::OrdinalIgnoreCase)) { if(-not($YesToAll -or $NoToAll -or $SourceSGrantedTrust.Contains($source) -or $sourcesDeniedTrust.Contains($source) -or $Force)) { $message = $QueryInstallUntrustedPackage -f ($psgetModuleInfo.Name, $psgetModuleInfo.RepositorySourceLocation) if($PSVersionTable.PSVersion -ge '5.0.0') { $sourceTrusted = $psCmdlet.ShouldContinue("$message", "$RepositoryIsNotTrusted",$true, [ref]$YesToAll, [ref]$NoToAll) } else { $sourceTrusted = $psCmdlet.ShouldContinue("$message", "$RepositoryIsNotTrusted", [ref]$YesToAll, [ref]$NoToAll) } if($sourceTrusted) { $SourceSGrantedTrust+=$source } else { $SourcesDeniedTrust+=$source } } } if($installationPolicy.Equals("trusted", [StringComparison]::OrdinalIgnoreCase) -or $SourceSGrantedTrust.Contains($source) -or $YesToAll -or $Force) { $PSBoundParameters["Force"] = $true $null = PackageManagement\Install-Package @PSBoundParameters } } } } } } } function Update-Module { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(SupportsShouldProcess=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkID=398576')] Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [Switch] $Force, [Parameter()] [switch] $AcceptLicense ) Begin { Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential # Module names already tried in the current pipeline $moduleNamesInPipeline = @() } Process { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } $GetPackageParameters = @{} $GetPackageParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule $GetPackageParameters["Provider"] = $script:PSModuleProviderName $GetPackageParameters["MessageResolver"] = $script:PackageManagementMessageResolverScriptBlock $GetPackageParameters['ErrorAction'] = 'SilentlyContinue' $GetPackageParameters['WarningAction'] = 'SilentlyContinue' $PSGetItemInfos = @() if($Name) { foreach($moduleName in $Name) { $GetPackageParameters['Name'] = $moduleName $installedPackages = PackageManagement\Get-Package @GetPackageParameters if(-not $installedPackages -and -not (Test-WildcardPattern -Name $moduleName)) { $availableModules = Get-Module -ListAvailable $moduleName -Verbose:$false | Microsoft.PowerShell.Utility\Select-Object -Unique -ErrorAction Ignore if(-not $availableModules) { $message = $LocalizedData.ModuleNotInstalledOnThisMachine -f ($moduleName) Write-Error -Message $message -ErrorId 'ModuleNotInstalledOnThisMachine' -Category InvalidOperation -TargetObject $moduleName } else { $message = $LocalizedData.ModuleNotInstalledUsingPowerShellGet -f ($moduleName) Write-Error -Message $message -ErrorId 'ModuleNotInstalledUsingInstallModuleCmdlet' -Category InvalidOperation -TargetObject $moduleName } continue } $installedPackages | Microsoft.PowerShell.Core\ForEach-Object {New-PSGetItemInfo -SoftwareIdentity $_ -Type $script:PSArtifactTypeModule} | Microsoft.PowerShell.Core\ForEach-Object { if(-not (Test-RunningAsElevated) -and $_.InstalledLocation.StartsWith($script:programFilesModulesPath, [System.StringComparison]::OrdinalIgnoreCase)) { if(-not (Test-WildcardPattern -Name $moduleName)) { $message = $LocalizedData.AdminPrivilegesRequiredForUpdate -f ($_.Name, $_.InstalledLocation) Write-Error -Message $message -ErrorId "AdminPrivilegesAreRequiredForUpdate" -Category InvalidOperation -TargetObject $moduleName } continue } $PSGetItemInfos += $_ } } } else { $PSGetItemInfos = PackageManagement\Get-Package @GetPackageParameters | Microsoft.PowerShell.Core\ForEach-Object {New-PSGetItemInfo -SoftwareIdentity $_ -Type $script:PSArtifactTypeModule} | Microsoft.PowerShell.Core\Where-Object { (Test-RunningAsElevated) -or $_.InstalledLocation.StartsWith($script:MyDocumentsModulesPath, [System.StringComparison]::OrdinalIgnoreCase) } } $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule foreach($psgetItemInfo in $PSGetItemInfos) { # Skip the module name if it is already tried in the current pipeline if($moduleNamesInPipeline -contains $psgetItemInfo.Name) { continue } $moduleNamesInPipeline += $psgetItemInfo.Name $message = $LocalizedData.CheckingForModuleUpdate -f ($psgetItemInfo.Name) Write-Verbose -Message $message $providerName = Get-ProviderName -PSCustomObject $psgetItemInfo if(-not $providerName) { $providerName = $script:NuGetProviderName } $PSBoundParameters["MessageResolver"] = $script:PackageManagementUpdateModuleMessageResolverScriptBlock $PSBoundParameters["Name"] = $psgetItemInfo.Name $PSBoundParameters['Source'] = $psgetItemInfo.Repository Get-PSGalleryApiAvailability -Repository (Get-SourceName -Location $psgetItemInfo.RepositorySourceLocation) $PSBoundParameters["PackageManagementProvider"] = $providerName $PSBoundParameters["InstallUpdate"] = $true if($psgetItemInfo.InstalledLocation.ToString().StartsWith($script:MyDocumentsModulesPath, [System.StringComparison]::OrdinalIgnoreCase)) { $PSBoundParameters["Scope"] = "CurrentUser" } else { $PSBoundParameters['Scope'] = 'AllUsers' } $sid = PackageManagement\Install-Package @PSBoundParameters } } } function Uninstall-Module { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(DefaultParameterSetName='NameParameterSet', SupportsShouldProcess=$true, HelpUri='https://go.microsoft.com/fwlink/?LinkId=526864')] Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0, ParameterSetName='NameParameterSet')] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputObject')] [ValidateNotNull()] [PSCustomObject[]] $InputObject, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ParameterSetName='NameParameterSet')] [switch] $AllVersions, [Parameter()] [Switch] $Force ) Process { $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters["MessageResolver"] = $script:PackageManagementUnInstallModuleMessageResolverScriptBlock $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule if($PSCmdlet.ParameterSetName -eq "InputObject") { $null = $PSBoundParameters.Remove("InputObject") foreach($inputValue in $InputObject) { if (($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSRepositoryItemInfo")) { ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $LocalizedData.InvalidInputObjectValue ` -ErrorId "InvalidInputObjectValue" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $inputValue } $PSBoundParameters["Name"] = $inputValue.Name $PSBoundParameters["RequiredVersion"] = $inputValue.Version $null = PackageManagement\Uninstall-Package @PSBoundParameters } } else { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -TestWildcardsInName ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion ` -AllVersions:$AllVersions if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } $null = PackageManagement\Uninstall-Package @PSBoundParameters } } } function Get-InstalledModule { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(HelpUri='https://go.microsoft.com/fwlink/?LinkId=526863')] Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter()] [switch] $AllVersions ) Process { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion ` -AllVersions:$AllVersions if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters["MessageResolver"] = $script:PackageManagementMessageResolverScriptBlock $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeModule PackageManagement\Get-Package @PSBoundParameters | Microsoft.PowerShell.Core\ForEach-Object {New-PSGetItemInfo -SoftwareIdentity $_ -Type $script:PSArtifactTypeModule} } } #endregion *-Module cmdlets #region Find-DscResource cmdlet function Find-DscResource { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(HelpUri = 'https://go.microsoft.com/fwlink/?LinkId=517196')] [outputtype('PSCustomObject[]')] Param ( [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [string] $ModuleName, [Parameter()] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter()] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter()] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter()] [switch] $AllVersions, [Parameter()] [ValidateNotNull()] [string[]] $Tag, [Parameter()] [ValidateNotNull()] [string] $Filter, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Repository ) Process { $PSBoundParameters['Includes'] = 'DscResource' if($PSBoundParameters.ContainsKey('Name')) { $PSBoundParameters['DscResource'] = $Name $null = $PSBoundParameters.Remove('Name') } if($PSBoundParameters.ContainsKey('ModuleName')) { $PSBoundParameters['Name'] = $ModuleName $null = $PSBoundParameters.Remove('ModuleName') } PowerShellGet\Find-Module @PSBoundParameters | Microsoft.PowerShell.Core\ForEach-Object { $psgetModuleInfo = $_ $psgetModuleInfo.Includes.DscResource | Microsoft.PowerShell.Core\ForEach-Object { if($Name -and ($Name -notcontains $_)) { return } $psgetDscResourceInfo = Microsoft.PowerShell.Utility\New-Object PSCustomObject -Property ([ordered]@{ Name = $_ Version = $psgetModuleInfo.Version ModuleName = $psgetModuleInfo.Name Repository = $psgetModuleInfo.Repository PSGetModuleInfo = $psgetModuleInfo }) $psgetDscResourceInfo.PSTypeNames.Insert(0, 'Microsoft.PowerShell.Commands.PSGetDscResourceInfo') $psgetDscResourceInfo } } } } #endregion Find-DscResource cmdlet #region Find-Command cmdlet function Find-Command { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(HelpUri = 'https://go.microsoft.com/fwlink/?LinkId=733636')] [outputtype('PSCustomObject[]')] Param ( [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [string] $ModuleName, [Parameter()] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter()] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter()] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter()] [switch] $AllVersions, [Parameter()] [ValidateNotNull()] [string[]] $Tag, [Parameter()] [ValidateNotNull()] [string] $Filter, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Repository ) Process { if($PSBoundParameters.ContainsKey('Name')) { $PSBoundParameters['Command'] = $Name $null = $PSBoundParameters.Remove('Name') } else { $PSBoundParameters['Includes'] = @('Cmdlet','Function') } if($PSBoundParameters.ContainsKey('ModuleName')) { $PSBoundParameters['Name'] = $ModuleName $null = $PSBoundParameters.Remove('ModuleName') } PowerShellGet\Find-Module @PSBoundParameters | Microsoft.PowerShell.Core\ForEach-Object { $psgetModuleInfo = $_ $psgetModuleInfo.Includes.Command | Microsoft.PowerShell.Core\ForEach-Object { if(($_ -eq "*") -or ($Name -and ($Name -notcontains $_))) { return } $psgetCommandInfo = Microsoft.PowerShell.Utility\New-Object PSCustomObject -Property ([ordered]@{ Name = $_ Version = $psgetModuleInfo.Version ModuleName = $psgetModuleInfo.Name Repository = $psgetModuleInfo.Repository PSGetModuleInfo = $psgetModuleInfo }) $psgetCommandInfo.PSTypeNames.Insert(0, 'Microsoft.PowerShell.Commands.PSGetCommandInfo') $psgetCommandInfo } } } } #endregion Find-Command cmdlet #region Find-RoleCapability cmdlet function Find-RoleCapability { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(HelpUri = 'https://go.microsoft.com/fwlink/?LinkId=718029')] [outputtype('PSCustomObject[]')] Param ( [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [string] $ModuleName, [Parameter()] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter()] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter()] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter()] [switch] $AllVersions, [Parameter()] [ValidateNotNull()] [string[]] $Tag, [Parameter()] [ValidateNotNull()] [string] $Filter, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Repository ) Process { $PSBoundParameters['Includes'] = 'RoleCapability' if($PSBoundParameters.ContainsKey('Name')) { $PSBoundParameters['RoleCapability'] = $Name $null = $PSBoundParameters.Remove('Name') } if($PSBoundParameters.ContainsKey('ModuleName')) { $PSBoundParameters['Name'] = $ModuleName $null = $PSBoundParameters.Remove('ModuleName') } PowerShellGet\Find-Module @PSBoundParameters | Microsoft.PowerShell.Core\ForEach-Object { $psgetModuleInfo = $_ $psgetModuleInfo.Includes.RoleCapability | Microsoft.PowerShell.Core\ForEach-Object { if($Name -and ($Name -notcontains $_)) { return } $psgetRoleCapabilityInfo = Microsoft.PowerShell.Utility\New-Object PSCustomObject -Property ([ordered]@{ Name = $_ Version = $psgetModuleInfo.Version ModuleName = $psgetModuleInfo.Name Repository = $psgetModuleInfo.Repository PSGetModuleInfo = $psgetModuleInfo }) $psgetRoleCapabilityInfo.PSTypeNames.Insert(0, 'Microsoft.PowerShell.Commands.PSGetRoleCapabilityInfo') $psgetRoleCapabilityInfo } } } } #endregion Find-RoleCapability cmdlet #region *-Script cmdlets function Publish-Script { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(SupportsShouldProcess=$true, PositionalBinding=$false, DefaultParameterSetName='PathParameterSet', HelpUri='https://go.microsoft.com/fwlink/?LinkId=619788')] Param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='PathParameterSet')] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='LiteralPathParameterSet')] [ValidateNotNullOrEmpty()] [string] $LiteralPath, [Parameter()] [ValidateNotNullOrEmpty()] [string] $NuGetApiKey, [Parameter()] [ValidateNotNullOrEmpty()] [string] $Repository = $Script:PSGalleryModuleSource, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter()] [switch] $Force ) Begin { if($script:isNanoServer -or $script:IsCoreCLR) { $message = $LocalizedData.PublishPSArtifactUnsupportedOnNano -f "Script" ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId 'PublishScriptIsNotSupportedOnPowerShellCoreEdition' ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $PSCmdlet ` -ErrorCategory InvalidOperation } Get-PSGalleryApiAvailability -Repository $Repository Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -BootstrapNuGetExe -Force:$Force } Process { $scriptFilePath = $null if($Path) { $scriptFilePath = Resolve-PathHelper -Path $Path -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $scriptFilePath -or -not (Microsoft.PowerShell.Management\Test-Path -Path $scriptFilePath -PathType Leaf)) { $errorMessage = ($LocalizedData.PathNotFound -f $Path) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "PathNotFound" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $Path ` -ErrorCategory InvalidArgument } } else { $scriptFilePath = Resolve-PathHelper -Path $LiteralPath -IsLiteralPath -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $scriptFilePath -or -not (Microsoft.PowerShell.Management\Test-Path -LiteralPath $scriptFilePath -PathType Leaf)) { $errorMessage = ($LocalizedData.PathNotFound -f $LiteralPath) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "PathNotFound" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $LiteralPath ` -ErrorCategory InvalidArgument } } if(-not $scriptFilePath.EndsWith('.ps1', [System.StringComparison]::OrdinalIgnoreCase)) { $errorMessage = ($LocalizedData.InvalidScriptFilePath -f $scriptFilePath) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "InvalidScriptFilePath" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $scriptFilePath ` -ErrorCategory InvalidArgument return } if($Repository -eq $Script:PSGalleryModuleSource) { $repo = Get-PSRepository -Name $Repository -ErrorAction SilentlyContinue -WarningAction SilentlyContinue if(-not $repo) { $message = $LocalizedData.PSGalleryNotFound -f ($Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId 'PSGalleryNotFound' ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Repository return } } else { $ev = $null $repo = Get-PSRepository -Name $Repository -ErrorVariable ev # Checking for the $repo object as well as terminating errors are not captured into ev on downlevel PowerShell versions. if($ev -or (-not $repo)) { return } } $DestinationLocation = $null if(Get-Member -InputObject $repo -Name $script:ScriptPublishLocation) { $DestinationLocation = $repo.ScriptPublishLocation } if(-not $DestinationLocation -or (-not (Microsoft.PowerShell.Management\Test-Path -Path $DestinationLocation) -and -not (Test-WebUri -uri $DestinationLocation))) { $message = $LocalizedData.PSRepositoryScriptPublishLocationIsMissing -f ($Repository, $Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "PSRepositoryScriptPublishLocationIsMissing" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Repository } $message = $LocalizedData.PublishLocation -f ($DestinationLocation) Write-Verbose -Message $message if(-not $NuGetApiKey.Trim()) { if(Microsoft.PowerShell.Management\Test-Path -Path $DestinationLocation) { $NuGetApiKey = "$(Get-Random)" } else { $message = $LocalizedData.NuGetApiKeyIsRequiredForNuGetBasedGalleryService -f ($Repository, $DestinationLocation) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "NuGetApiKeyIsRequiredForNuGetBasedGalleryService" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument } } $providerName = Get-ProviderName -PSCustomObject $repo if($providerName -ne $script:NuGetProviderName) { $message = $LocalizedData.PublishScriptSupportsOnlyNuGetBasedPublishLocations -f ($DestinationLocation, $Repository, $Repository) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $message ` -ErrorId "PublishScriptSupportsOnlyNuGetBasedPublishLocations" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $Repository } if($Path) { $PSScriptInfo = Test-ScriptFileInfo -Path $scriptFilePath } else { $PSScriptInfo = Test-ScriptFileInfo -LiteralPath $scriptFilePath } if(-not $PSScriptInfo) { # Test-ScriptFileInfo throws the actual error return } $scriptName = $PSScriptInfo.Name # Copy the source script file to temp location to publish $tempScriptPath = Microsoft.PowerShell.Management\Join-Path -Path $script:TempPath ` -ChildPath "$(Microsoft.PowerShell.Utility\Get-Random)\$scriptName" $null = Microsoft.PowerShell.Management\New-Item -Path $tempScriptPath -ItemType Directory -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false if($Path) { Microsoft.PowerShell.Management\Copy-Item -Path $scriptFilePath -Destination $tempScriptPath -Force -Recurse -Confirm:$false -WhatIf:$false } else { Microsoft.PowerShell.Management\Copy-Item -LiteralPath $scriptFilePath -Destination $tempScriptPath -Force -Recurse -Confirm:$false -WhatIf:$false } try { $FindParameters = @{ Name = $scriptName Repository = $Repository Tag = 'PSModule' Verbose = $VerbosePreference ErrorAction = 'SilentlyContinue' WarningAction = 'SilentlyContinue' Debug = $DebugPreference } if($Credential) { $FindParameters[$script:Credential] = $Credential } # Check if the specified script name is already used for a module on the specified repository # Use Find-Module to check if that name is already used as module name $modulePSGetItemInfo = Find-Module @FindParameters | Microsoft.PowerShell.Core\Where-Object {$_.Name -eq $scriptName} | Microsoft.PowerShell.Utility\Select-Object -Last 1 -ErrorAction Ignore if($modulePSGetItemInfo) { $message = $LocalizedData.SpecifiedNameIsAlearyUsed -f ($scriptName, $Repository, 'Find-Module') ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "SpecifiedNameIsAlearyUsed" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation ` -ExceptionObject $scriptName } $null = $FindParameters.Remove('Tag') $currentPSGetItemInfo = $null $currentPSGetItemInfo = Find-Script @FindParameters | Microsoft.PowerShell.Core\Where-Object {$_.Name -eq $scriptName} | Microsoft.PowerShell.Utility\Select-Object -Last 1 -ErrorAction Ignore if($currentPSGetItemInfo) { if($currentPSGetItemInfo.Version -eq $PSScriptInfo.Version) { $message = $LocalizedData.ScriptVersionIsAlreadyAvailableInTheGallery -f ($scriptName, $PSScriptInfo.Version, $currentPSGetItemInfo.Version, $currentPSGetItemInfo.RepositorySourceLocation) ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId 'ScriptVersionIsAlreadyAvailableInTheGallery' ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation } elseif(-not $Force -and ($currentPSGetItemInfo.Version -gt $PSScriptInfo.Version)) { $message = $LocalizedData.ScriptVersionShouldBeGreaterThanGalleryVersion -f ($scriptName, $PSScriptInfo.Version, $currentPSGetItemInfo.Version, $currentPSGetItemInfo.RepositorySourceLocation) ThrowError -ExceptionName "System.InvalidOperationException" ` -ExceptionMessage $message ` -ErrorId "ScriptVersionShouldBeGreaterThanGalleryVersion" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidOperation } } $shouldProcessMessage = $LocalizedData.PublishScriptwhatIfMessage -f ($PSScriptInfo.Version, $scriptName) if($Force -or $PSCmdlet.ShouldProcess($shouldProcessMessage, "Publish-Script")) { $PublishPSArtifactUtility_Params = @{ PSScriptInfo=$PSScriptInfo NugetApiKey=$NuGetApiKey Destination=$DestinationLocation Repository=$Repository NugetPackageRoot=$tempScriptPath Verbose=$VerbosePreference WarningAction=$WarningPreference ErrorAction=$ErrorActionPreference Debug=$DebugPreference } if ($PSBoundParameters.ContainsKey('Credential')) { $PublishPSArtifactUtility_Params.Add('Credential',$Credential) } Publish-PSArtifactUtility @PublishPSArtifactUtility_Params } } finally { Microsoft.PowerShell.Management\Remove-Item $tempScriptPath -Force -Recurse -ErrorAction Ignore -WarningAction SilentlyContinue -Confirm:$false -WhatIf:$false } } } function Find-Script { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(HelpUri='https://go.microsoft.com/fwlink/?LinkId=619785')] [outputtype("PSCustomObject[]")] Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter()] [switch] $AllVersions, [Parameter()] [switch] $IncludeDependencies, [Parameter()] [ValidateNotNull()] [string] $Filter, [Parameter()] [ValidateNotNull()] [string[]] $Tag, [Parameter()] [ValidateNotNull()] [ValidateSet('Function','Workflow')] [string[]] $Includes, [Parameter()] [ValidateNotNull()] [string[]] $Command, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Repository, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential ) Begin { Get-PSGalleryApiAvailability -Repository $Repository Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential } Process { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion ` -AllVersions:$AllVersions if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } $PSBoundParameters['Provider'] = $script:PSModuleProviderName $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeScript if($PSBoundParameters.ContainsKey("Repository")) { $PSBoundParameters["Source"] = $Repository $null = $PSBoundParameters.Remove("Repository") $ev = $null $repositories = Get-PSRepository -Name $Repository -ErrorVariable ev -verbose:$false if($ev) { return } $RepositoriesWithoutScriptSourceLocation = $false foreach($repo in $repositories) { if(-not $repo.ScriptSourceLocation) { $message = $LocalizedData.ScriptSourceLocationIsMissing -f ($repo.Name) Write-Error -Message $message ` -ErrorId 'ScriptSourceLocationIsMissing' ` -Category InvalidArgument ` -TargetObject $repo.Name ` -Exception 'System.ArgumentException' $RepositoriesWithoutScriptSourceLocation = $true } } if($RepositoriesWithoutScriptSourceLocation) { return } } $PSBoundParameters["MessageResolver"] = $script:PackageManagementMessageResolverScriptBlockForScriptCmdlets $scriptsFoundInPSGallery = @() # No Telemetry must be performed if PSGallery is not in the supplied list of Repositories $isRepositoryNullOrPSGallerySpecified = $false if ($Repository -and ($Repository -Contains $Script:PSGalleryModuleSource)) { $isRepositoryNullOrPSGallerySpecified = $true } elseif(-not $Repository) { $psgalleryRepo = Get-PSRepository -Name $Script:PSGalleryModuleSource ` -ErrorAction SilentlyContinue ` -WarningAction SilentlyContinue # And check for IsDefault? if($psgalleryRepo) { $isRepositoryNullOrPSGallerySpecified = $true } } PackageManagement\Find-Package @PSBoundParameters | Microsoft.PowerShell.Core\ForEach-Object { $psgetItemInfo = New-PSGetItemInfo -SoftwareIdentity $_ -Type $script:PSArtifactTypeScript $psgetItemInfo if ($psgetItemInfo -and $isRepositoryNullOrPSGallerySpecified -and $script:TelemetryEnabled -and ($psgetItemInfo.Repository -eq $Script:PSGalleryModuleSource)) { $scriptsFoundInPSGallery += $psgetItemInfo.Name } } # Perform Telemetry if Repository is not supplied or Repository contains PSGallery # We are only interested in finding artifacts not in PSGallery if ($isRepositoryNullOrPSGallerySpecified) { Log-ArtifactNotFoundInPSGallery -SearchedName $Name -FoundName $scriptsFoundInPSGallery -operationName PSGET_FIND_SCRIPT } } } function Save-Script { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(DefaultParameterSetName='NameAndPathParameterSet', HelpUri='https://go.microsoft.com/fwlink/?LinkId=619786', SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='NameAndPathParameterSet')] [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputOjectAndPathParameterSet')] [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputOjectAndLiteralPathParameterSet')] [ValidateNotNull()] [PSCustomObject[]] $InputObject, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Repository, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndPathParameterSet')] [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='InputOjectAndPathParameterSet')] [string] $Path, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='NameAndLiteralPathParameterSet')] [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName='InputOjectAndLiteralPathParameterSet')] [string] $LiteralPath, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter()] [switch] $Force, [Parameter()] [switch] $AcceptLicense ) Begin { Get-PSGalleryApiAvailability -Repository $Repository Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential # Script names already tried in the current pipeline for InputObject parameterset $scriptNamesInPipeline = @() } Process { $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters["MessageResolver"] = $script:PackageManagementSaveScriptMessageResolverScriptBlock $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeScript # When -Force is specified, Path will be created if not available. if(-not $Force) { if($Path) { $destinationPath = Resolve-PathHelper -Path $Path -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $destinationPath -or -not (Microsoft.PowerShell.Management\Test-path $destinationPath)) { $errorMessage = ($LocalizedData.PathNotFound -f $Path) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "PathNotFound" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $Path ` -ErrorCategory InvalidArgument } $PSBoundParameters['Path'] = $destinationPath } else { $destinationPath = Resolve-PathHelper -Path $LiteralPath -IsLiteralPath -CallerPSCmdlet $PSCmdlet | Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction Ignore if(-not $destinationPath -or -not (Microsoft.PowerShell.Management\Test-Path -LiteralPath $destinationPath)) { $errorMessage = ($LocalizedData.PathNotFound -f $LiteralPath) ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $errorMessage ` -ErrorId "PathNotFound" ` -CallerPSCmdlet $PSCmdlet ` -ExceptionObject $LiteralPath ` -ErrorCategory InvalidArgument } $PSBoundParameters['LiteralPath'] = $destinationPath } } if($Name) { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -TestWildcardsInName ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } if($PSBoundParameters.ContainsKey("Repository")) { $PSBoundParameters["Source"] = $Repository $null = $PSBoundParameters.Remove("Repository") $ev = $null $repositories = Get-PSRepository -Name $Repository -ErrorVariable ev -verbose:$false if($ev) { return } $RepositoriesWithoutScriptSourceLocation = $false foreach($repo in $repositories) { if(-not $repo.ScriptSourceLocation) { $message = $LocalizedData.ScriptSourceLocationIsMissing -f ($repo.Name) Write-Error -Message $message ` -ErrorId 'ScriptSourceLocationIsMissing' ` -Category InvalidArgument ` -TargetObject $repo.Name ` -Exception 'System.ArgumentException' $RepositoriesWithoutScriptSourceLocation = $true } } if($RepositoriesWithoutScriptSourceLocation) { return } } $null = PackageManagement\Save-Package @PSBoundParameters } elseif($InputObject) { $null = $PSBoundParameters.Remove("InputObject") foreach($inputValue in $InputObject) { if (($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSRepositoryItemInfo")) { ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $LocalizedData.InvalidInputObjectValue ` -ErrorId "InvalidInputObjectValue" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $inputValue } $psRepositoryItemInfo = $inputValue # Skip the script name if it is already tried in the current pipeline if($scriptNamesInPipeline -contains $psRepositoryItemInfo.Name) { continue } $scriptNamesInPipeline += $psRepositoryItemInfo.Name if ($psRepositoryItemInfo.PowerShellGetFormatVersion -and ($script:SupportedPSGetFormatVersionMajors -notcontains $psRepositoryItemInfo.PowerShellGetFormatVersion.Major)) { $message = $LocalizedData.NotSupportedPowerShellGetFormatVersionScripts -f ($psRepositoryItemInfo.Name, $psRepositoryItemInfo.PowerShellGetFormatVersion, $psRepositoryItemInfo.Name) Write-Error -Message $message -ErrorId "NotSupportedPowerShellGetFormatVersion" -Category InvalidOperation continue } $PSBoundParameters["Name"] = $psRepositoryItemInfo.Name $PSBoundParameters["RequiredVersion"] = $psRepositoryItemInfo.Version $PSBoundParameters['Source'] = $psRepositoryItemInfo.Repository $PSBoundParameters["PackageManagementProvider"] = (Get-ProviderName -PSCustomObject $psRepositoryItemInfo) $null = PackageManagement\Save-Package @PSBoundParameters } } } } function Install-Script { <# .ExternalHelp PSGet.psm1-help.xml #> [CmdletBinding(DefaultParameterSetName='NameParameterSet', HelpUri='https://go.microsoft.com/fwlink/?LinkId=619784', SupportsShouldProcess=$true)] Param ( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='NameParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0, ParameterSetName='InputObject')] [ValidateNotNull()] [PSCustomObject[]] $InputObject, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $MinimumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $MaximumVersion, [Parameter(ValueFromPipelineByPropertyName=$true, ParameterSetName='NameParameterSet')] [ValidateNotNull()] [Version] $RequiredVersion, [Parameter(ParameterSetName='NameParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Repository, [Parameter()] [ValidateSet("CurrentUser","AllUsers")] [string] $Scope = 'AllUsers', [Parameter()] [Switch] $NoPathUpdate, [Parameter(ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Uri] $Proxy, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $ProxyCredential, [Parameter(ValueFromPipelineByPropertyName=$true)] [PSCredential] $Credential, [Parameter()] [switch] $Force, [Parameter()] [switch] $AcceptLicense ) Begin { Get-PSGalleryApiAvailability -Repository $Repository if(-not (Test-RunningAsElevated) -and ($Scope -ne "CurrentUser")) { # Throw an error when Install-Script is used as a non-admin user and '-Scope CurrentUser' is not specified $AdminPrivilegeErrorMessage = $LocalizedData.InstallScriptNeedsCurrentUserScopeParameterForNonAdminUser -f @($script:ProgramFilesScriptsPath, $script:MyDocumentsScriptsPath) $AdminPrivilegeErrorId = 'InstallScriptNeedsCurrentUserScopeParameterForNonAdminUser' ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $AdminPrivilegeErrorMessage ` -ErrorId $AdminPrivilegeErrorId ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument } # Check and add the scope path to PATH environment variable if($Scope -eq 'AllUsers') { $scopePath = $script:ProgramFilesScriptsPath } else { $scopePath = $script:MyDocumentsScriptsPath } ValidateAndSet-PATHVariableIfUserAccepts -Scope $Scope ` -ScopePath $scopePath ` -NoPathUpdate:$NoPathUpdate ` -Force:$Force Install-NuGetClientBinaries -CallerPSCmdlet $PSCmdlet -Proxy $Proxy -ProxyCredential $ProxyCredential # Script names already tried in the current pipeline for InputObject parameterset $scriptNamesInPipeline = @() $YesToAll = $false $NoToAll = $false $SourceSGrantedTrust = @() $SourcesDeniedTrust = @() } Process { $RepositoryIsNotTrusted = $LocalizedData.RepositoryIsNotTrusted $QueryInstallUntrustedPackage = $LocalizedData.QueryInstallUntrustedScriptPackage $PackageTarget = $LocalizedData.InstallScriptwhatIfMessage $PSBoundParameters["Provider"] = $script:PSModuleProviderName $PSBoundParameters["MessageResolver"] = $script:PackageManagementInstallScriptMessageResolverScriptBlock $PSBoundParameters[$script:PSArtifactType] = $script:PSArtifactTypeScript $PSBoundParameters['Scope'] = $Scope if($PSCmdlet.ParameterSetName -eq "NameParameterSet") { $ValidationResult = Validate-VersionParameters -CallerPSCmdlet $PSCmdlet ` -Name $Name ` -TestWildcardsInName ` -MinimumVersion $MinimumVersion ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion if(-not $ValidationResult) { # Validate-VersionParameters throws the error. # returning to avoid further execution when different values are specified for -ErrorAction parameter return } if($PSBoundParameters.ContainsKey("Repository")) { $PSBoundParameters["Source"] = $Repository $null = $PSBoundParameters.Remove("Repository") $ev = $null $repositories = Get-PSRepository -Name $Repository -ErrorVariable ev -verbose:$false if($ev) { return } $RepositoriesWithoutScriptSourceLocation = $false foreach($repo in $repositories) { if(-not $repo.ScriptSourceLocation) { $message = $LocalizedData.ScriptSourceLocationIsMissing -f ($repo.Name) Write-Error -Message $message ` -ErrorId 'ScriptSourceLocationIsMissing' ` -Category InvalidArgument ` -TargetObject $repo.Name ` -Exception 'System.ArgumentException' $RepositoriesWithoutScriptSourceLocation = $true } } if($RepositoriesWithoutScriptSourceLocation) { return } } if(-not $Force) { foreach($scriptName in $Name) { # Throw an error if there is a command with the same name and -force is not specified. $cmd = Microsoft.PowerShell.Core\Get-Command -Name $scriptName ` -ErrorAction Ignore ` -WarningAction SilentlyContinue if($cmd) { # Check if this script was already installed, may be with -Force $InstalledScriptInfo = Test-ScriptInstalled -Name $scriptName ` -ErrorAction SilentlyContinue ` -WarningAction SilentlyContinue if(-not $InstalledScriptInfo) { $message = $LocalizedData.CommandAlreadyAvailable -f ($scriptName) Write-Error -Message $message -ErrorId CommandAlreadyAvailableWitScriptName -Category InvalidOperation # return if only single name is specified if($scriptName -eq $Name) { return } } } } } $null = PackageManagement\Install-Package @PSBoundParameters } elseif($PSCmdlet.ParameterSetName -eq "InputObject") { $null = $PSBoundParameters.Remove("InputObject") foreach($inputValue in $InputObject) { if (($inputValue.PSTypeNames -notcontains "Microsoft.PowerShell.Commands.PSRepositoryItemInfo") -and ($inputValue.PSTypeNames -notcontains "Deserialized.Microsoft.PowerShell.Commands.PSRepositoryItemInfo")) { ThrowError -ExceptionName "System.ArgumentException" ` -ExceptionMessage $LocalizedData.InvalidInputObjectValue ` -ErrorId "InvalidInputObjectValue" ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument ` -ExceptionObject $inputValue } $psRepositoryItemInfo = $inputValue # Skip the script name if it is already tried in the current pipeline if($scriptNamesInPipeline -contains $psRepositoryItemInfo.Name) { continue } $scriptNamesInPipeline += $psRepositoryItemInfo.Name if ($psRepositoryItemInfo.PowerShellGetFormatVersion -and ($script:SupportedPSGetFormatVersionMajors -notcontains $psRepositoryItemInfo.PowerShellGetFormatVersion.Major)) { $message = $LocalizedData.NotSupportedPowerShellGetFormatVersionScripts -f ($psRepositoryItemInfo.Name, $psRepositoryItemInfo.PowerShellGetFormatVersion, $psRepositoryItemInfo.Name) Write-Error -Message $message -ErrorId "NotSupportedPowerShellGetFormatVersion" -Category InvalidOperation continue } $PSBoundParameters["Name"] = $psRepositoryItemInfo.Name $PSBoundParameters["RequiredVersion"] = $psRepositoryItemInfo.Version $PSBoundParameters['Source'] = $psRepositoryItemInfo.Repository $PSBoundParameters["PackageManagementProvider"] = (Get-ProviderName -PSCustomObject $psRepositoryItemInfo) $InstalledScriptInfo = Test-ScriptInstalled -Name $psRepositoryItemInfo.Name if(-not $Force -and $InstalledScriptInfo) { $message = $LocalizedData.ScriptAlreadyInstalledVerbose -f ($InstalledScriptInfo.Version, $InstalledScriptInfo.Name, $InstalledScriptInfo.ScriptBase) Write-Verbose -Message $message } else { # Throw an error if there is a command with the same name and -force is not specified. if(-not $Force) { $cmd = Microsoft.PowerShell.Core\Get-Command -Name $psRepositoryItemInfo.Name ` -ErrorAction Ignore ` -WarningAction SilentlyContinue if($cmd) { $message = $LocalizedData.CommandAlreadyAvailable -f ($psRepositoryItemInfo.Name) Write-Error -Message $message -ErrorId CommandAlreadyAvailableWitScriptName -Category InvalidOperation continue } } $source = $psRepositoryItemInfo.Repository $installationPolicy = (Get-PSRepository -Name $source).InstallationPolicy $ShouldProcessMessage |