PowerShell / PSResourceGet

PSResourceGet is the package manager for PowerShell
https://www.powershellgallery.com/packages/Microsoft.PowerShell.PSResourceGet
MIT License
483 stars 92 forks source link

Install-PSResource fails on fresh VM: `Value cannot be null. (Parameter 'path1')` #1527

Closed odegroot closed 7 months ago

odegroot commented 7 months ago

Prerequisites

Steps to reproduce

I have an Azure Virtual Machine Scale Set (VMSS) that provides my Azure DevOps (ADO) build agents. I use the Custom Script Extension for Linux to run a script that installs dependencies on new VM instances. One of the steps in this script is using Install-PSResource to install some PowerShell modules. This step fails with a weird error message.

Can you change Install-PSResource such that it can deal with this situation, or that it gives an error message that makes clear what it needs from the runtime environment?

Expected behavior

Install-PSResource installs the requested module without errors.

-or-

Install-PSResource fails with a helpful error message.

Actual behavior

Install-PSResource fails with the following error.

Install-PSResource: Value cannot be null. (Parameter 'path1')

Note that path1 does not refer to any inputs for Install-PSResource, so it's not clear what is missing here.

After this, when I SSH to the VM instance and retry the exact same Install-PSResource command, it installs the module just fine.

It seems that when the post-deployment-script runs, the VM is not quite yet in a state that Install-PSResource expects.

Error details

Get-Error:

Exception             : System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
                           at System.ArgumentNullException.Throw(String paramName)
                           at System.IO.Path.Combine(String path1, String path2, String path3, String path4)
                           at Microsoft.PowerShell.PSResourceGet.UtilClasses.Utils.GetStandardPlatformPaths(PSCmdlet psCmdlet, String& localUserDir, String& allUsersDir)
                           at Microsoft.PowerShell.PSResourceGet.UtilClasses.Utils.GetPathsFromEnvVarAndScope(PSCmdlet psCmdlet, Nullable`1 scope)
                           at Microsoft.PowerShell.PSResourceGet.UtilClasses.Utils.GetAllInstallationPaths(PSCmdlet psCmdlet, Nullable`1 scope)
                           at Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource.BeginProcessing()
                           at System.Management.Automation.Cmdlet.DoBeginProcessing()
                           at System.Management.Automation.CommandProcessorBase.DoBegin()
TargetObject          :
CategoryInfo          : NotSpecified: (:) [Install-PSResource], ArgumentNullExc
                        eption
FullyQualifiedErrorId : System.ArgumentNullException,Microsoft.PowerShell.PSRes
                        ourceGet.Cmdlets.InstallPSResource
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}

Environment data

Get-Module Microsoft.PowerShell.PSResourceGet:

ModuleType Version    PreRelease Name                                ExportedCo
                                                                     mmands
---------- -------    ---------- ----                                ----------
Binary     1.0.1                 Microsoft.PowerShell.PSResourceGet  {Find-PSR…

$PSVersionTable:

Name                           Value
----                           -----
PSVersion                      7.4.1
PSEdition                      Core
GitCommitId                    7.4.1
OS                             Ubuntu 20.04.6 LTS
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

gci env::

Name                           Value
----                           -----
_                              /usr/bin/nohup
AZURE_GUEST_AGENT_CONTAINER_ID 047ea4ad-740d-4f48-a0ec-7eb7685250ea
AZURE_GUEST_AGENT_EXTENSION_P… /var/lib/waagent/Microsoft.Azure.Extensions.Cus…
AZURE_GUEST_AGENT_EXTENSION_S… [{"Key": "ExtensionTelemetryPipeline", "Value":…
AZURE_GUEST_AGENT_EXTENSION_V… 2.1.10
AZURE_GUEST_AGENT_UNINSTALL_C… NOT_RUN
AZURE_GUEST_AGENT_WIRE_PROTOC… 168.63.129.16
CLR_ICU_VERSION_OVERRIDE       60.2
ConfigSequenceNumber           1
INVOCATION_ID                  338834b4a5cf469590f55f44afa871d3
JOURNAL_STREAM                 8:24260
LANG                           C.UTF-8
PATH                           /snap/powershell/262/opt/powershell:/usr/local/…
POWERSHELL_DISTRIBUTION_CHANN… PSSnap
PSModulePath                   /tmp/pwsh-root-98288ff9-5712-4a14-9a11-23693b9c…
PWD                            /var/lib/waagent/custom-script/download/1
SGX_AESM_ADDR                  1
SHLVL                          0
SNAP                           /snap/powershell/262
SNAP_ARCH                      amd64
SNAP_COMMON                    /var/snap/powershell/common
SNAP_CONTEXT                   PC1IwfLw3f7p1oEYbgJKsiCct5Dhl6EXxlWaVpG-rZy76EK…
SNAP_COOKIE                    PC1IwfLw3f7p1oEYbgJKsiCct5Dhl6EXxlWaVpG-rZy76EK…
SNAP_DATA                      /var/snap/powershell/262
SNAP_EUID                      0
SNAP_INSTANCE_KEY
SNAP_INSTANCE_NAME             powershell
SNAP_LIBRARY_PATH              /var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/…
SNAP_NAME                      powershell
SNAP_REAL_HOME                 /root
SNAP_REEXEC
SNAP_REVISION                  262
SNAP_UID                       0
SNAP_USER_COMMON               /root/snap/powershell/common
SNAP_USER_DATA                 /root/snap/powershell/262
SNAP_VERSION                   7.4.1

Visuals

No response

odegroot commented 7 months ago

This seems to be triggered by the absence of the HOME environment variable.

When I SSH to the VM (after provisioning is done), then temporarily unset the HOME var, and retry Install-PSResource, then it fails with the same error.

pwsh -c 'Remove-Item Env:\HOME; gci env:; Install-PSResource -Name "Az.Accounts" -ErrorAction Stop -Verbose; Get-Error'
Name                           Value
----                           -----
_                              /usr/bin/pwsh
LANG                           C.UTF-8
LESSCLOSE                      /usr/bin/lesspipe %s %s
LESSOPEN                       | /usr/bin/lesspipe %s
LOGNAME                        root
LS_COLORS                      rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=…
MAIL                           /var/mail/root
OLDPWD                         /root
PATH                           /opt/microsoft/powershell/7:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
PSModulePath                   /root/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/powershell/7/Modules
PWD                            /var/lib/waagent/custom-script/download/1
SGX_AESM_ADDR                  1
SHELL                          /bin/bash
SHLVL                          1
SUDO_COMMAND                   /bin/bash
SUDO_GID                       1000
SUDO_UID                       1000
SUDO_USER                      odg
TERM                           xterm-256color
USER                           root
XDG_DATA_DIRS                  /usr/local/share:/usr/share:/var/lib/snapd/desktop
Install-PSResource: Value cannot be null. (Parameter 'path1')

Exception             : System.ArgumentNullException: Value cannot be null. (Parameter 'path1')
                           at System.ArgumentNullException.Throw(String paramName)
                           at System.IO.Path.Combine(String path1, String path2, String path3, String path4)
                           at Microsoft.PowerShell.PSResourceGet.UtilClasses.Utils.GetStandardPlatformPaths(PSCmdlet psCmdlet, String& localUserDir, String& allUsersDir)
                           at Microsoft.PowerShell.PSResourceGet.UtilClasses.Utils.GetPathsFromEnvVarAndScope(PSCmdlet psCmdlet, Nullable`1 scope)
                           at Microsoft.PowerShell.PSResourceGet.UtilClasses.Utils.GetAllInstallationPaths(PSCmdlet psCmdlet, Nullable`1 scope)
                           at Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource.BeginProcessing()
                           at System.Management.Automation.Cmdlet.DoBeginProcessing()
                           at System.Management.Automation.CommandProcessorBase.DoBegin()
TargetObject          :
CategoryInfo          : NotSpecified: (:) [Install-PSResource], ArgumentNullException
FullyQualifiedErrorId : System.ArgumentNullException,Microsoft.PowerShell.PSResourceGet.Cmdlets.InstallPSResource
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}

When I leave the HOME var intact, then Install-PSResource works fine.

pwsh -c 'gci env:; Install-PSResource -Name "Az.Accounts" -ErrorAction Stop -Verbose; Get-Error'
Name                           Value
----                           -----
_                              /usr/bin/pwsh
HOME                           /root
LANG                           C.UTF-8
LESSCLOSE                      /usr/bin/lesspipe %s %s
LESSOPEN                       | /usr/bin/lesspipe %s
LOGNAME                        root
LS_COLORS                      rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=…
MAIL                           /var/mail/root
OLDPWD                         /root
PATH                           /opt/microsoft/powershell/7:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
PSModulePath                   /root/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/powershell/7/Modules
PWD                            /var/lib/waagent/custom-script/download/1
SGX_AESM_ADDR                  1
SHELL                          /bin/bash
SHLVL                          1
SUDO_COMMAND                   /bin/bash
SUDO_GID                       1000
SUDO_UID                       1000
SUDO_USER                      odg
TERM                           xterm-256color
USER                           root
XDG_DATA_DIRS                  /usr/local/share:/usr/share:/var/lib/snapd/desktop
VERBOSE: All paths to search: '/root/.local/share/powershell/Modules'
VERBOSE: All paths to search: '/root/.local/share/powershell/Scripts'
VERBOSE: Retrieving directories in the path '/root/.local/share/powershell/Modules'
VERBOSE: Retrieving directories in the path '/root/.local/share/powershell/Scripts'
VERBOSE: All paths to search: '/root/.local/share/powershell/Modules/Az.Storage'
VERBOSE: All paths to search: '/root/.local/share/powershell/Modules/Az.Accounts'
VERBOSE: Attempting to search for packages in 'PSGallery'
WARNING: Resource 'Az.Accounts' with version '2.15.0' is already installed.  If you would like to reinstall, please run the cmdlet again with the -Reinstall parameter
VERBOSE: Attempting to delete '/tmp/7ea3a084-7388-4b93-b7c2-051b933d1c7e'
VERBOSE: Successfully deleted '/tmp/7ea3a084-7388-4b93-b7c2-051b933d1c7e'

Looking at the source code (Utils.cs#L986), there seems to be some variable shadowing going on. Note that s_tempHome is declared twice:

private static string s_tempHome = null;
var s_tempHome = Path.Combine(…);

Presumably this is the cause of the ArgumentNullException.

odegroot commented 7 months ago

Presumably introduced in #1464.

alerickson commented 7 months ago

@odegroot you're correct. I was able to repro your issue on my MacOS and after removing the second declaration of s_tempHome (ie. just setting the value here instead of redeclaring it), the test packages install correctly. I also checked if Get-InstalledPSResource would then retrieve it correctly and it does.

I'll get a PR for that out shortly and we should have this out with our release next week.