# A PowerShell script that adds the latest version of the Azure Artifacts credential provider # plugin for Dotnet and/or NuGet to ~/.nuget/plugins directory # To install netcore, run installcredprovider.ps1 # To install netcore and netfx, run installcredprovider.ps1 -AddNetfx # To overwrite existing plugin with the latest version, run installcredprovider.ps1 -Force # To use a specific version of a credential provider, run installcredprovider.ps1 -Version "1.0.1" or installcredprovider.ps1 -Version "1.0.1" -Force param( # whether or not to install netfx folder for nuget [switch]$AddNetfx, # whether or not to install netfx 4.8.1 folder for nuget [switch]$AddNetfx48, # override existing cred provider with the latest version [switch]$Force, # install the version specified [string]$Version, # install the .NET 6 cred provider instead of NetCore3.1 [switch]$InstallNet6 = $true, # install the .NET 8 cred provider instead of NetCore3.1 [switch]$InstallNet8 ) $script:ErrorActionPreference='Stop' # Without this, System.Net.WebClient.DownloadFile will fail on a client with TLS 1.0/1.1 disabled if ([Net.ServicePointManager]::SecurityProtocol.ToString().Split(',').Trim() -notcontains 'Tls12') { [Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12 } if ($Version.StartsWith("0.") -and $InstallNet6 -eq $True) { Write-Error "You cannot install the .Net 6 version with versions lower than 1.0.0" return } if (($Version.StartsWith("0.") -or $Version.StartsWith("1.0") -or $Version.StartsWith("1.1") -or $Version.StartsWith("1.2")) -and ($InstallNet8 -eq $True -or $AddNetfx48 -eq $True)) { Write-Error "You cannot install the .Net 8 or NetFX 4.8.1 version or with versions lower than 1.3.0" return } if ($AddNetfx -eq $True -and $AddNetfx48 -eq $True) { Write-Error "Please select a single .Net framework version to install" return } if ($InstallNet6 -eq $True -and $InstallNet8 -eq $True) { # InstallNet6 defaults to true, in the case of .Net 8 install, overwrite $InstallNet6 = $False } $userProfilePath = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile); if ($userProfilePath -ne '') { $profilePath = $userProfilePath } else { $profilePath = $env:UserProfile } $tempPath = [System.IO.Path]::GetTempPath() $pluginLocation = [System.IO.Path]::Combine($profilePath, ".nuget", "plugins"); $tempZipLocation = [System.IO.Path]::Combine($tempPath, "CredProviderZip"); $localNetcoreCredProviderPath = [System.IO.Path]::Combine("netcore", "CredentialProvider.Microsoft"); $localNetfxCredProviderPath = [System.IO.Path]::Combine("netfx", "CredentialProvider.Microsoft"); $fullNetfxCredProviderPath = [System.IO.Path]::Combine($pluginLocation, $localNetfxCredProviderPath) $fullNetcoreCredProviderPath = [System.IO.Path]::Combine($pluginLocation, $localNetcoreCredProviderPath) $netfxExists = Test-Path -Path ($fullNetfxCredProviderPath) $netcoreExists = Test-Path -Path ($fullNetcoreCredProviderPath) # Check if plugin already exists if -Force swich is not set if (!$Force) { if ($AddNetfx -eq $True -and $netfxExists -eq $True -and $netcoreExists -eq $True) { Write-Host "The netcore and netfx Credential Providers are already in $pluginLocation" return } if ($AddNetfx -eq $False -and $netcoreExists -eq $True) { Write-Host "The netcore Credential Provider is already in $pluginLocation" return } } # Get the zip file from the GitHub release $releaseUrlBase = "https://api.github.com/repos/Microsoft/artifacts-credprovider/releases" $versionError = "Unable to find the release version $Version from $releaseUrlBase" $releaseId = "latest" if (![string]::IsNullOrEmpty($Version)) { try { $releases = Invoke-WebRequest -UseBasicParsing $releaseUrlBase $releaseJson = $releases | ConvertFrom-Json $correctReleaseVersion = $releaseJson | ? { $_.name -eq $Version } $releaseId = $correctReleaseVersion.id } catch { Write-Error $versionError return } } if (!$releaseId) { Write-Error $versionError return } $releaseUrl = [System.IO.Path]::Combine($releaseUrlBase, $releaseId) $releaseUrl = $releaseUrl.Replace("\","/") $zipFile = "Microsoft.NetCore3.NuGet.CredentialProvider.zip" if ($Version.StartsWith("0.")) { # versions lower than 1.0.0 installed NetCore2 zip $zipFile = "Microsoft.NetCore2.NuGet.CredentialProvider.zip" } if ($InstallNet6 -eq $True) { $zipFile = "Microsoft.Net6.NuGet.CredentialProvider.zip" } if ($InstallNet8 -eq $True) { $zipFile = "Microsoft.Net8.NuGet.CredentialProvider.zip" } if ($AddNetfx -eq $True) { $zipFile = "Microsoft.NuGet.CredentialProvider.zip" } if ($AddNetfx48 -eq $True) { $zipFile = "Microsoft.NetFx48.NuGet.CredentialProvider.zip" } function InstallZip { Write-Verbose "Using $zipFile" try { Write-Host "Fetching release $releaseUrl" $release = Invoke-WebRequest -UseBasicParsing $releaseUrl if (!$release) { throw ("Unable to make Web Request to $releaseUrl") } $releaseJson = $release.Content | ConvertFrom-Json if (!$releaseJson) { throw ("Unable to get content from JSON") } $zipAsset = $releaseJson.assets | ? { $_.name -eq $zipFile } if (!$zipAsset) { throw ("Unable to find asset $zipFile from release json object") } $packageSourceUrl = $zipAsset.browser_download_url if (!$packageSourceUrl) { throw ("Unable to find download url from asset $zipAsset") } } catch { Write-Error ("Unable to resolve the browser download url from $releaseUrl `nError: " + $_.Exception.Message) return } # Create temporary location for the zip file handling Write-Verbose "Creating temp directory for the Credential Provider zip: $tempZipLocation" if (Test-Path -Path $tempZipLocation) { Remove-Item $tempZipLocation -Force -Recurse } New-Item -ItemType Directory -Force -Path $tempZipLocation # Download credential provider zip to the temp location $pluginZip = ([System.IO.Path]::Combine($tempZipLocation, $zipFile)) Write-Host "Downloading $packageSourceUrl to $pluginZip" try { $client = New-Object System.Net.WebClient $client.DownloadFile($packageSourceUrl, $pluginZip) } catch { Write-Error "Unable to download $packageSourceUrl to the location $pluginZip" } # Extract zip to temp directory Write-Host "Extracting zip to the Credential Provider temp directory $tempZipLocation" Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($pluginZip, $tempZipLocation) } # Call InstallZip function InstallZip # Remove existing content and copy netfx directories to plugins directory if ($AddNetfx -eq $True -or $AddNetfx48 -eq $True) { if ($netfxExists) { Write-Verbose "Removing existing content from $fullNetfxCredProviderPath" Remove-Item $fullNetfxCredProviderPath -Force -Recurse } $tempNetfxPath = [System.IO.Path]::Combine($tempZipLocation, "plugins", $localNetfxCredProviderPath) Write-Verbose "Copying Credential Provider from $tempNetfxPath to $fullNetfxCredProviderPath" Copy-Item $tempNetfxPath -Destination $fullNetfxCredProviderPath -Force -Recurse } # Microsoft.NuGet.CredentialProvider.zip that installs netfx provider installs .netcore3.1 version # If InstallNet6 is also true we need to replace netcore cred provider with net6 if ($AddNetfx -eq $True -and $InstallNet6 -eq $True) { $zipFile = "Microsoft.Net6.NuGet.CredentialProvider.zip" Write-Verbose "Installing Net6" InstallZip } if ($AddNetfx -eq $True -and $InstallNet8 -eq $True) { $zipFile = "Microsoft.Net8.NuGet.CredentialProvider.zip" Write-Verbose "Installing Net8" InstallZip } # Remove existing content and copy netcore directories to plugins directory if ($netcoreExists) { Write-Verbose "Removing existing content from $fullNetcoreCredProviderPath" Remove-Item $fullNetcoreCredProviderPath -Force -Recurse } $tempNetcorePath = [System.IO.Path]::Combine($tempZipLocation, "plugins", $localNetcoreCredProviderPath) Write-Verbose "Copying Credential Provider from $tempNetcorePath to $fullNetcoreCredProviderPath" Copy-Item $tempNetcorePath -Destination $fullNetcoreCredProviderPath -Force -Recurse # Remove $tempZipLocation directory Write-Verbose "Removing the Credential Provider temp directory $tempZipLocation" Remove-Item $tempZipLocation -Force -Recurse Write-Host "Credential Provider installed successfully"