Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Powershell one-line install on Windows 11 error - "You cannot call a method on a null-valued expression" #3749

Closed
pmolodo opened this issue May 2, 2024 · 14 comments · Fixed by #3751
Assignees
Labels
bug Something isn't working windows only This only affects Windows

Comments

@pmolodo
Copy link
Contributor

pmolodo commented May 2, 2024

Describe the bug

I did a fresh install of Windows 11, and one of the first things I did on it was try to install chezmoi.

I followed the install docs to install via a Powershell one liner, and ran this:

iex "&{$(irm 'https://get.chezmoi.io/ps1')}"

Unfortunately, it returned this error:

You cannot call a method on a null-valued expression.
At line:1 char:1
+ &{<#
+ ~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

To reproduce

See above. I was on a fresh install but it was a company managed Windows 11, so it's not at completely generic / stock settings.

Expected behavior

Chezmoi should download + install.

@twpayne twpayne added the bug Something isn't working label May 2, 2024
@twpayne
Copy link
Owner

twpayne commented May 2, 2024

FWIW I get the same error in Powershell on my Windows 10 machine. Assigned issue to our expert :)

@twpayne twpayne added the windows only This only affects Windows label May 2, 2024
@bradenhilton
Copy link
Collaborator

@pmolodo Would you mind downloading the script to a local file and running that to see if a more descriptive error message is output?

We test the install script via GitHub Actions, which should at least approximate a fresh Windows install, so I'm not sure at the moment what the problem is exactly. I'll try to trigger the workflow tomorrow and see if it's also stopped working.

I can't reproduce this with either a local copy of the script or the remote command:

.\install.ps1
found version 2.48.0 for latest/windows/amd64
installed C:\Users\User\bin\chezmoi.exe
iex "&{$(irm 'https://get.chezmoi.io/ps1')}"
found version 2.48.0 for latest/windows/amd64
installed C:\Users\User\bin\chezmoi.exe

The error message can suggest a fault with a code, but the local script still works for me even if I set strict mode to version 3 (currently the most strict). I also don't get any errors out of PSScriptAnalyzer.

@twpayne
Copy link
Owner

twpayne commented May 3, 2024

Disclaimer: I know nothing about Windows.

I tried the following:

  1. Visited get.chezmoi.io/ps1 in Edge on Windows 10.
  2. This downloaded a file called ps1.
  3. Opened PowerShell and ran the following:
PS C:\Users\twpay\Downloads> mv ps1 install.ps1
PS C:\Users\twpay\Downloads> .\install.ps1
.\install.ps1 : File C:\Users\twpay\Downloads\install.ps1 cannot be loaded. The file
C:\Users\twpay\Downloads\install.ps1 is not digitally signed. You cannot run this script on the current system. For
more information about running scripts and setting execution policy, see about_Execution_Policies at
https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ .\install.ps1
+ ~~~~~~~~~~~~~
    + CategoryInfo          : SecurityError: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
PS C:\Users\twpay\Downloads> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       Undefined


PS C:\Users\twpay\Downloads> Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): y
PS C:\Users\twpay\Downloads> .\install.ps1

Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your
computer. If you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning
message. Do you want to run C:\Users\twpay\Downloads\install.ps1?
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"): r
C:\Users\twpay\Downloads\install.ps1 : You cannot call a method on a null-valued expression.
At line:1 char:1
+ .\install.ps1
+ ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [install.ps1], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,install.ps1

PS C:\Users\twpay\Downloads>

@bradenhilton
Copy link
Collaborator

@twpayne That makes two of us.

I don't know how to proceed here given that I only have my own environment available to me. I don't think I do anything outlandish with my PowerShell/Windows setup. At the moment, it isn't clear to me if this is caused by a script error or some relatively new Windows change. You may also recall how extensively we tested the changes I made to the script, and nothing like this came up then.

The error message also gives no hints. Would you or @pmolodo be willing to step through the script in a debugger and see where it fails? I'm particularly interested in if it fails to run completely, or perhaps if it fails on a web request which means a variable is null when it shouldn't be, etc.

I used VS Code with the PowerShell extension when writing the new script in my chezmoi fork. Here is the launch.json configuration I used, unchanged:

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "install.ps1",
      "type": "PowerShell",
      "request": "launch",
      "script": "${workspaceFolder}/assets/scripts/install.ps1",
      "cwd": "${cwd}",
      "args": ["-d", "doctor"]
    },
  ]
}

I will open a PR tomorrow to make the workflow run again and see where that leads.

@pmolodo
Copy link
Contributor Author

pmolodo commented May 3, 2024 via email

@bradenhilton
Copy link
Collaborator

The workflow ran successfully with strict mode both disabled and enabled.

I'm not smart (or stupid) enough to say with 100% certainty that the script is not at fault, but I am starting to think this may be a Windows issue that could be resolved with one or more pre-install steps being added to the docs, I just don't know what they are yet. I thought about perhaps messing around with a Windows image.

@pmolodo
Copy link
Contributor Author

pmolodo commented May 4, 2024 via email

@bradenhilton
Copy link
Collaborator

I use pwsh where I can.

$PSVersionTable.PSVersion

Major  Minor  Patch  PreReleaseLabel BuildLabel
-----  -----  -----  --------------- ----------
7      4      2Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine    RemoteSigned
$PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      22621  2506Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       Undefined

@twpayne
Copy link
Owner

twpayne commented May 6, 2024

OK, it seems I have PowerShell 5.1 on my Windows 10 machine which is missing the OSArchitecture property:

PS C:\Users\twpay\chezmoi\assets\scripts> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  4355
PS C:\Users\twpay\chezmoi\assets\scripts> git status
On branch pr/bradenhilton/3751
Your branch is up to date with 'bradenhilton/ps1-workflow'.

nothing to commit, working tree clean
PS C:\Users\twpay\chezmoi\assets\scripts> .\install.ps1
C:\Users\twpay\chezmoi\assets\scripts\install.ps1 : The property 'OSArchitecture' cannot be found on this object.
Verify that the property exists.
At line:1 char:1
+ .\install.ps1
+ ~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [install.ps1], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict,install.ps1

@bradenhilton
Copy link
Collaborator

@twpayne Thanks for looking into this.

The Windows PowerShell build is usually updated when Windows is updated. The build number in your output indicates that you are using build 19041 of Windows 10, which was released in May of 2020.

Would you mind providing the output of the following commands from PowerShell?

[System.Runtime.InteropServices.RuntimeInformation] | Get-Member -Static
Get-CimInstance -Class Win32_OperatingSystem | Get-Member -MemberType Property

Here is my output for all commands:

$PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      22621  2506
[System.Runtime.InteropServices.RuntimeInformation] | Get-Member -Static


   TypeName: System.Runtime.InteropServices.RuntimeInformation

Name                 MemberType Definition
----                 ---------- ----------
Equals               Method     static bool Equals(System.Object objA, System.Object objB)
IsOSPlatform         Method     static bool IsOSPlatform(System.Runtime.InteropServices.OSPlatform osPlatform)
ReferenceEquals      Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
FrameworkDescription Property   static string FrameworkDescription {get;}
OSArchitecture       Property   static System.Runtime.InteropServices.Architecture OSArchitecture {get;}
OSDescription        Property   static string OSDescription {get;}
ProcessArchitecture  Property   static System.Runtime.InteropServices.Architecture ProcessArchitecture {get;}
Get-CimInstance -Class Win32_OperatingSystem | Get-Member -MemberType Property


   TypeName: Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_OperatingSystem

Name                                      MemberType Definition
----                                      ---------- ----------
...
OSArchitecture                            Property   string OSArchitecture {get;}
...

There are a few more ways to determine bitness, I'll look into them.

@twpayne
Copy link
Owner

twpayne commented May 6, 2024

Here you go. For reference, I installed Windows 10 around December 2022 but have kept it up to date with Windows Update. I've been unable to update it since January 2024 due to this Windows bug.

I'll re-install the system at some point, but I'll wait until we've resolved this so we don't lose the machine that reproduces the problem :)

PS C:\Users\twpay> [System.Runtime.InteropServices.RuntimeInformation] | Get-Member -Static


   TypeName: System.Runtime.InteropServices.RuntimeInformation

Name            MemberType Definition
----            ---------- ----------
Equals          Method     static bool Equals(System.Object objA, System.Object objB)
IsOSPlatform    Method     static bool IsOSPlatform(System.Runtime.InteropServices.OSPlatform platform)
new             Method     System.Runtime.InteropServices.RuntimeInformation new()
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
PS C:\Users\twpay> Get-CimInstance -Class Win32_OperatingSystem | Get-Member -MemberType Property


   TypeName: Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_OperatingSystem

Name                                      MemberType Definition
----                                      ---------- ----------
BootDevice                                Property   string BootDevice {get;}
BuildNumber                               Property   string BuildNumber {get;}
BuildType                                 Property   string BuildType {get;}
Caption                                   Property   string Caption {get;}
CodeSet                                   Property   string CodeSet {get;}
CountryCode                               Property   string CountryCode {get;}
CreationClassName                         Property   string CreationClassName {get;}
CSCreationClassName                       Property   string CSCreationClassName {get;}
CSDVersion                                Property   string CSDVersion {get;}
CSName                                    Property   string CSName {get;}
CurrentTimeZone                           Property   int16 CurrentTimeZone {get;}
DataExecutionPrevention_32BitApplications Property   bool DataExecutionPrevention_32BitApplications {get;}
DataExecutionPrevention_Available         Property   bool DataExecutionPrevention_Available {get;}
DataExecutionPrevention_Drivers           Property   bool DataExecutionPrevention_Drivers {get;}
DataExecutionPrevention_SupportPolicy     Property   byte DataExecutionPrevention_SupportPolicy {get;}
Debug                                     Property   bool Debug {get;}
Description                               Property   string Description {get;set;}
Distributed                               Property   bool Distributed {get;}
EncryptionLevel                           Property   uint32 EncryptionLevel {get;}
ForegroundApplicationBoost                Property   byte ForegroundApplicationBoost {get;set;}
FreePhysicalMemory                        Property   uint64 FreePhysicalMemory {get;}
FreeSpaceInPagingFiles                    Property   uint64 FreeSpaceInPagingFiles {get;}
FreeVirtualMemory                         Property   uint64 FreeVirtualMemory {get;}
InstallDate                               Property   CimInstance#DateTime InstallDate {get;}
LargeSystemCache                          Property   uint32 LargeSystemCache {get;}
LastBootUpTime                            Property   CimInstance#DateTime LastBootUpTime {get;}
LocalDateTime                             Property   CimInstance#DateTime LocalDateTime {get;}
Locale                                    Property   string Locale {get;}
Manufacturer                              Property   string Manufacturer {get;}
MaxNumberOfProcesses                      Property   uint32 MaxNumberOfProcesses {get;}
MaxProcessMemorySize                      Property   uint64 MaxProcessMemorySize {get;}
MUILanguages                              Property   string[] MUILanguages {get;}
Name                                      Property   string Name {get;}
NumberOfLicensedUsers                     Property   uint32 NumberOfLicensedUsers {get;}
NumberOfProcesses                         Property   uint32 NumberOfProcesses {get;}
NumberOfUsers                             Property   uint32 NumberOfUsers {get;}
OperatingSystemSKU                        Property   uint32 OperatingSystemSKU {get;}
Organization                              Property   string Organization {get;}
OSArchitecture                            Property   string OSArchitecture {get;}
OSLanguage                                Property   uint32 OSLanguage {get;}
OSProductSuite                            Property   uint32 OSProductSuite {get;}
OSType                                    Property   uint16 OSType {get;}
OtherTypeDescription                      Property   string OtherTypeDescription {get;}
PAEEnabled                                Property   bool PAEEnabled {get;}
PlusProductID                             Property   string PlusProductID {get;}
PlusVersionNumber                         Property   string PlusVersionNumber {get;}
PortableOperatingSystem                   Property   bool PortableOperatingSystem {get;}
Primary                                   Property   bool Primary {get;}
ProductType                               Property   uint32 ProductType {get;}
PSComputerName                            Property   string PSComputerName {get;}
RegisteredUser                            Property   string RegisteredUser {get;}
SerialNumber                              Property   string SerialNumber {get;}
ServicePackMajorVersion                   Property   uint16 ServicePackMajorVersion {get;}
ServicePackMinorVersion                   Property   uint16 ServicePackMinorVersion {get;}
SizeStoredInPagingFiles                   Property   uint64 SizeStoredInPagingFiles {get;}
Status                                    Property   string Status {get;}
SuiteMask                                 Property   uint32 SuiteMask {get;}
SystemDevice                              Property   string SystemDevice {get;}
SystemDirectory                           Property   string SystemDirectory {get;}
SystemDrive                               Property   string SystemDrive {get;}
TotalSwapSpaceSize                        Property   uint64 TotalSwapSpaceSize {get;}
TotalVirtualMemorySize                    Property   uint64 TotalVirtualMemorySize {get;}
TotalVisibleMemorySize                    Property   uint64 TotalVisibleMemorySize {get;}
Version                                   Property   string Version {get;}
WindowsDirectory                          Property   string WindowsDirectory {get;}

@bradenhilton
Copy link
Collaborator

@twpayne I think you and @pmolodo are experiencing two different issues. I believe you are unable to run the script at all due to [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture not being present and throwing an error, but @pmolodo successfully ran the script locally, and is only experiencing an issue with the remote command.

I'm slightly confused, as System.Runtime.InteropServices.RuntimeInformation requires Windows PowerShell's built-in .NET framework version to be at least 4.7.1, and it can potentially be as low as 4.5, which PowerShell 5.1 shipped with.

I ran the installers again with windows-2019, which uses build 17763 (which is an older build than yours), and they still ran successfully.

A simple fix for your issue would be to rearrange the function such that it checks the edition of PowerShell and simply uses CIM on Windows PowerShell (the "Desktop" edition).

@bradenhilton
Copy link
Collaborator

bradenhilton commented May 10, 2024

Small update: I can now reproduce this in a Windows Docker container:

docker run -it mcr.microsoft.com/windows:ltsc2019
Microsoft Windows [Version 10.0.17763.5696]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\> iex "&{$(irm 'https://get.chezmoi.io/ps1')}"
You cannot call a method on a null-valued expression.
At line:1 char:1
+ &{<#
+ ~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

The modifications I made to the script in #3751 appear to work as expected:

PS C:\> iex "&{$(irm 'https://raw.githubusercontent.com/twpayne/chezmoi/33087eeeffa1f8347c16387a6e96a366919105c3/assets/scripts/install.ps1')}"
found version 2.48.0 for latest/windows/amd64
installed C:\bin\chezmoi.exe

@twpayne
Copy link
Owner

twpayne commented May 25, 2024

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working windows only This only affects Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants