PowerShell package source confirmation - powershell

I'm trying to create a function that will automatically install, update and import on demand a PowerShell module from repository PSGallery and this will be run on a build server so I have to avoid any kind of confirmation prompts. This function will be called quite often and will not try to install or update modules if the module is already loaded to the session (only the first time).
# Already imported? Let's not go further with updates and import again...
if (Get-Module -Name $moduleName)
{
Write-Host "'$moduleName' is already imported to the current session!"
return
}
If the module is not already installed, I will try to install it. The problem is when I get to the step that I have to install the NuGet PackageManagement provider (before importing PowerShellGet module needed to install modules from PSGallery). I do the following cmdlet:
Install-PackageProvider -Name "NuGet" -Confirm:$false -Verbose
But I get the following confirmation prompt:
I could solve this issue by using the -Force parameter like that:
Install-PackageProvider -Name "NuGet" -Confirm:$false -Force -Verbose
But the problem I see with that solution (might not be a big deal) is that using -Force will download and install again NuGet every time even if the installed version is up to date. Without the -Force parameter, it will just skip it if the version is up to date and I would much rather that.
Is there a way to set the package source 'https://oneget.org/nuget-2.8.5.208.package.swidtag' as trusted so I don't get the confirmation prompt again without having to use -Force parameter?

Actually, if you run Get-PackageProvider -Name "NuGet" -Force it will automatically download and install it if its not installed. If it is installed, it returns NuGet as an object. My PowerShell version is 5.1.14393.1480.
Original Response:
Maybe you could just check to see if its available and then run your command?
$NuGetProvider = Get-PackageProvider -Name "NuGet" -ErrorAction SilentlyContinue
if ( -not $NugetProvider )
{
Install-PackageProvider -Name "NuGet" -Confirm:$false -Force -Verbose
}

Not sure if this will help, but here goes nothing:
Can you use the cmd version of try-catch using errorlevel?
Install-PackageProvider -Name "NuGet" -Confirm:$false -Verbose
if errorlevel 1 GOTO Forced
exit /b
:Forced
Install-PackageProvider -Name "NuGet" -Confirm:$false -Force -Verbose

How about using the -ForceBoostrap parameter on Get-PackageProvider, e.g.
Get-PackageProvider -Name "nuget" -ForceBootstrap

Related

Windows 10 Version Update using PowerShell

Am I faced with such a problem that I need to update Widows 10 to next build (for example from 1903 to 1909) using PowerShell.
I use next methods:
1)
$Updates = Start-WUScan
Install-WUUpdates -Updates $Updates
2)
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Install-Module -Name PSWindowsUpdate -Confirm:$False -Force
Get-Package -Name PSWindowsUpdate
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted -Force
$WinUpdates=Get-WindowsUpdate -MicrosoftUpdate -Verbose
Install-WindowsUpdate -KBArticleID $WinUpdates.kb -AcceptAll
Both of these options work great, they find and install updates. BUT! All these updates are for the current build only. Updates to the transition to the next build are not found.
Does anyone know what I'm doing wrong or how to install an update that will allow me to upgrade to the next version of Windows?
I found an article about how you can do a feature upgrade with PowerShell:
$dir = 'C:\_Windows_FU\packages'
mkdir $dir
$webClient = New-Object System.Net.WebClient
$url = 'https://go.microsoft.com/fwlink/?LinkID=799445'
$file = "$($dir)\Win10Upgrade.exe"
$webClient.DownloadFile($url,$file)
Start-Process -FilePath $file -ArgumentList '/quietinstall /skipeula /auto upgrade /copylogs $dir'
I couldn't test it. Here is the source: https://social.technet.microsoft.com/Forums/en-US/51104081-4ed7-4fdd-8b12-5d1f5be532ae/windows-10-feature-update-via-cmd-powershell-or-gpo?forum=win10itprogeneral
using this manual I was able to update the test computer tutorial to get list of windows updates:
Add-WUServiceManager -ServiceID "7971f918-a847-4430-9279-4a52d1efe18d" -AddServiceFlag 7
Get-WUlist -MicrosoftUpdate
But remember in list can be wrong size of updates....
Notice that when installing a build upgrade with PSWindowsUpdate, restart does not yet finalize upgrade. When you have restarted from PowerShell after PSWindowsUpdate has downloaded and installed build upgrade, it is in fact only initialized, not installed.
You must restart once more from Start > Power > Update and restart
Also you can find usefull info here

Warning while install-module PowerShellGet

While installing PowerShellGet, I perform the following:
Install-PackageProvider Nuget –force –verbose
then I Exit, try running the following:
Install-Module –Name PowerShellGet –Force –Verbose
When I do this, I get the error:
This error occurs when I try to install other modules too, like MSOnline, Azure etc.
I have the latest version of Powershell and also the necessary modules.
I feel that the reason is due to the PowershellGet file.
Is there a way to resolve this issue?
You need to register the PowerShell repository before installing PowerShellGet. Try this
Register-PSRepository -Name “PSGallery” -SourceLocation “https://www.powershellgallery.com/api/v2/" -InstallationPolicy Trusted

Upgrade AzureRM Powershell on Hosted 2017 Agent (VSTS - Visual Studio Team Services)

I am using release management through Visual Studio Teams Services (online). We use Hosted build Agents and I really want to avoid the overhead of managing custom agents.
One item I do need is the AzureRM PowerShell module. Versions up to 5.1.1 are available on the agent but I need 6.0.0.
What I would like to do is use a step in my release process (PowerShell) to aquire version 6.0.0 and use thart instead, however I cant quite get it to work. I have tried a few approaches that have all come unstuck, the current one is:
Write-Output "------------------ Install package provider ------------------"
Find-PackageProvider -Name "NuGet" | Install-PackageProvider -Scope CurrentUser -Force
Write-Output "------------------ Remove Modules ------------------"
Get-Module -ListAvailable | Where-Object {$_.Name -like 'AzureRM*'} | Remove-Module
Write-Output "------------------ Install the AzureRM version we want - 6.0.1! ------------------"
Install-Package AzureRM -RequiredVersion 6.0.1 -Scope CurrentUser -Force
Write-Output "------------------ Import AzureRM 6.0.1 ------------------"
Import-Module AzureRM -RequiredVersion 6.0.1
This all works fine (i.e. does not crash...) but then when I try and use one of the 6.0.1 cmdlets I get an error.
Get-AzureRmADGroup : The Azure PowerShell session has not been
properly initialized. Please import the module and try again.
Any idea of where I am going wrong or alternate strategies I can use to deploy AzureRM 6.0.1 and use it on a hosted agent?
Thanks to Murray for the initial point in the right direction, to show what I was hoping to do wasn't impossible!
I initially tried to do this within the Azure PowerShell task and got pretty far but hit a dead end with AzureRm.Profile as you cannot unload an old version.
The trick was to understanding how the AzureRM VSTS task does it's dependency setup, it effectively takes the "Azure Powershell Version" string in the VSTS UI and uses it to define an additional search path in the PSModules environmental variable i.e. C:\Modules\azurerm_5.1.1.
It will look in that directory, before searching the user profile, then the global modules path.
As soon as it finds the module it performs the Azure login, which will hamper any hope of removing the module after.
So if you instead use a plain powershell task i.e. one that AzureRM isn't loaded into (as Murray also concluded):
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser
Install-Module -Name AzureRM -RequiredVersion 6.2.1 -Force -Scope CurrentUser -AllowClobber
Notably install-module won't be installing to c:\modules like the vsts image generation project.
I seemed to need AllowClobber to get around problems overriding old powershell versions when experimenting, but I suspect I don't need that anymore.
The elegant solution kicks in when next using the Azure PowerShell script.
The preferred powershell version field filled in with 6.2.1 will add C:\Modules\azurerm_6.2.1 to the PSModules path. This doesn't exist, but thankfully because PSModules still includes the user specific modules path, so our 6.2.1 is loaded by itself!
Luckily the AzureRM.Profile from 5.1.1 is forwards compatible enough that the service principal login performed by the Azure Powershell task still works.
Running
Get-Module AzureRm
Get-AzureRmContext
Will output the versions you are hoping for:
Notably if it weren't able to login, I think System.AccessToken could be used (if the option is switched on in the agent phase level).
Diagnostic Techniques if the workaround needs tweaking:
Things that helped greatly, reading through the code that loads in AzureRM in the task:
https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/AzurePowerShellV3/AzurePowerShell.ps1#L80
https://github.com/Microsoft/vsts-tasks/blob/0703b8869041d64db994934bde97de167787ed2e/Tasks/Common/VstsAzureHelpers_/ImportFunctions.ps1
https://github.com/Microsoft/vsts-tasks/blob/master/Tasks/AzurePowerShellV3/Utility.ps1#L18
And also how the VSTS image is generated:
https://github.com/Microsoft/vsts-image-generation/blob/2f57db26dc30ae0f257a3415d26eaa8eea0febf9/images/win/scripts/Installers/Install-AzureModules.ps1
Enabing System.Debug = true as a environment release variable.
Then using VSCode's Log File Highlighter plugin
I'd encourage anyone who's interested to vote in: https://github.com/Microsoft/vsts-image-generation/issues/149
As the AzureRM version at the time of writing is waaaay out of date on the VSTS Hosted 2017 agent.
Unfortunately I can't submit a PR to upgrade it, as it's pulled in via a zip file hosted privately.
I finally figured it out - adding an answer for anyone else that suffers the same.
The key is to login after the AzureRM module is upgraded.
PowerShell code:
Write-Output "------------------ Start: Upgrade AzureRM on build host ------------------"
Write-Output "- - - - - Install package provider"
Install-PackageProvider -Name NuGet -Force -Scope CurrentUser
Write-Output "- - - - - List Modules Before"
Get-Module -ListAvailable| where {$_.Name -Like “*AzureRM*”} | Select Name, Version
Write-Output "- - - - - Remove alll existing AzureRM Modules"
Get-Module -ListAvailable | Where-Object {$_.Name -like '*AzureRM*'} | Remove-Module -Force
Write-Output "- - - - - Install AzureRM 6.0.1"
Install-Module -Name AzureRM -RequiredVersion 6.0.1 -Force -Scope CurrentUser
Write-Output "- - - - - Import AzureRM 6.0.1"
Import-Module AzureRM -Force -Verbose -Scope Local
Write-Output "- - - - - List Modules After"
Get-Module -ListAvailable| where {$_.Name -Like “*AzureRM*”} | Select Name, Version
Write-Output "------------------ End: Upgrade AzureRM on build host ------------------"
Write-Output "------------------ Start: LoginToAzure ------------------"
$SecurePassword = ConvertTo-SecureString $AdminPassword -AsPlainText -Force
$AdminCredential = New-Object System.Management.Automation.PSCredential ($AdminUserEmailAddress, $SecurePassword)
Login-AzureRmAccount -Credential $AdminCredential
Get-AzureRmSubscription –SubscriptionId $SubscriptionId | Select-AzureRmSubscription
Write-Output "------------------ End: LoginToAzure ------------------"

Download nuget.exe using Powershell [duplicate]

As far as I can tell, NuGet is meant to be installed as a Visual Studio extension:
http://docs.nuget.org/docs/start-here/installing-nuget
But what if I need NuGet on a machine that doesn't have VS installed?
Specifically, I would like to install NuGet with a PowerShell script.
Run Powershell with Admin rights
Type the below PowerShell security protocol command for TLS12:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Here's a short PowerShell script to do what you probably expect:
$sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$targetNugetExe = "$rootPath\nuget.exe"
Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe
Set-Alias nuget $targetNugetExe -Scope Global -Verbose
Note that Invoke-WebRequest cmdlet arrived with PowerShell v3.0. This article gives the idea.
This also seems to do it.
PS Example:
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Without having Visual Studio, you can grab Nuget from: http://nuget.org/nuget.exe
For command-line executions using this, check out: http://docs.nuget.org/docs/reference/command-line-reference
With respect to Powershell, just copy the nuget.exe to the machine. No installation required, just execute it using commands from the above documentation.
With PowerShell but without the need to create a script:
Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile Nuget.exe
None of the above solutions worked for me, I found an article that explained the issue. The security protocols on the system were deprecated and therefore displayed an error message that no match was found for the ProviderPackage.
Here is a the basic steps for upgrading your security protocols:
Run both cmdlets to set .NET Framework strong cryptography registry keys. After that, restart PowerShell and check if the security protocol TLS 1.2 is added. As of last, install the PowerShellGet module.
The first cmdlet is to set strong cryptography on 64 bit .Net Framework (version 4 and above).
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
1
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
The second cmdlet is to set strong cryptography on 32 bit .Net Framework (version 4 and above).
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
1
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Restart Powershell and check for supported security protocols.
[PS] C:\>[Net.ServicePointManager]::SecurityProtocol
Tls, Tls11, Tls12
1
2
[PS] C:\>[Net.ServicePointManager]::SecurityProtocol
Tls, Tls11, Tls12
Run the command Install-Module PowershellGet -Force and press Y to install NuGet provider, follow with Enter.
[PS] C:\>Install-Module PowershellGet -Force
NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\administrator.EXOIP\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install
and import the NuGet provider now?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y
[PS] C:\>Install-Module PowershellGet -Force
NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\administrator.EXOIP\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install
and import the NuGet provider now?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y

Install NuGet via PowerShell script

As far as I can tell, NuGet is meant to be installed as a Visual Studio extension:
http://docs.nuget.org/docs/start-here/installing-nuget
But what if I need NuGet on a machine that doesn't have VS installed?
Specifically, I would like to install NuGet with a PowerShell script.
Run Powershell with Admin rights
Type the below PowerShell security protocol command for TLS12:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Here's a short PowerShell script to do what you probably expect:
$sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$targetNugetExe = "$rootPath\nuget.exe"
Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe
Set-Alias nuget $targetNugetExe -Scope Global -Verbose
Note that Invoke-WebRequest cmdlet arrived with PowerShell v3.0. This article gives the idea.
This also seems to do it.
PS Example:
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Without having Visual Studio, you can grab Nuget from: http://nuget.org/nuget.exe
For command-line executions using this, check out: http://docs.nuget.org/docs/reference/command-line-reference
With respect to Powershell, just copy the nuget.exe to the machine. No installation required, just execute it using commands from the above documentation.
With PowerShell but without the need to create a script:
Invoke-WebRequest https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile Nuget.exe
None of the above solutions worked for me, I found an article that explained the issue. The security protocols on the system were deprecated and therefore displayed an error message that no match was found for the ProviderPackage.
Here is a the basic steps for upgrading your security protocols:
Run both cmdlets to set .NET Framework strong cryptography registry keys. After that, restart PowerShell and check if the security protocol TLS 1.2 is added. As of last, install the PowerShellGet module.
The first cmdlet is to set strong cryptography on 64 bit .Net Framework (version 4 and above).
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
1
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
The second cmdlet is to set strong cryptography on 32 bit .Net Framework (version 4 and above).
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
1
[PS] C:\>Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Restart Powershell and check for supported security protocols.
[PS] C:\>[Net.ServicePointManager]::SecurityProtocol
Tls, Tls11, Tls12
1
2
[PS] C:\>[Net.ServicePointManager]::SecurityProtocol
Tls, Tls11, Tls12
Run the command Install-Module PowershellGet -Force and press Y to install NuGet provider, follow with Enter.
[PS] C:\>Install-Module PowershellGet -Force
NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\administrator.EXOIP\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install
and import the NuGet provider now?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y
[PS] C:\>Install-Module PowershellGet -Force
NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\administrator.EXOIP\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install
and import the NuGet provider now?
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y