PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

Error starting PowerShell 7.4.0+

Open giggio opened this issue 2 years ago • 18 comments

Prerequisites

Steps to reproduce

  1. Install PowerShell 7.4.0
  2. Start it
  3. Create a powershell.config.json and set PSModulePath to multiple paths, separated by ; (path separator char) (see reference).
  4. See it fail

Expected behavior

It starts, like 7.3 did.

Actual behavior

It fails with:

PowerShell 7.4.0
The shell cannot be started. A failure occurred during initialization:
Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'startIndex')

Error details

Not possible.

Environment data

Not possible, but it is version 7.4.0.

Visuals

This is starting from Nushell:

from nu

This is starting it from Windows Terminal:

from wt

Additional context

Downloaded and installed this file: https://github.com/PowerShell/PowerShell/releases/download/v7.4.0/PowerShell-7.4.0-win-x64.msi

I debugged and found out that the exception is ocurring at this location (ModuleIntrinsics.UpdatePath): https://github.com/PowerShell/PowerShell/blob/ad2bf787e4e7dfde9123a67349cf1ae6ccdfc984/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs#L1278

The arguments for UpdatePath are: path: a string with a ; separated list of paths pathToAdd: another string with a ; separated list of paths insertIndex: 0

The call that is failing is the one to path.IndexOf, which is passed ; and -1 (which is the result from the call to PathContainsSubstring).

The problem only happens because pathToAdd has several paths with the ; separator. If it was a single path without ; it would work.

The issue seems to have been introduced in commit 3710671c16de9bcbd945389a22a88b994cd02bcd.

giggio avatar Nov 16 '23 20:11 giggio

Can you check with "Add or Remove programs" settings that there is only one PowerShell MSI installed, and you don't have both 7.3.9 and 7.4.0?

The reason I say that is I found I had both installed, one with a normal MSI icon, the other with a PowerShell icon.

rhubarb-geek-nz avatar Nov 16 '23 21:11 rhubarb-geek-nz

@rhubarb-geek-nz I did, I hadn't.

giggio avatar Nov 16 '23 23:11 giggio

There are at least 4 ways to install Pwsh on Windows: From MSStore, via MSI, via Winget and Unzipping the download. Which one did you use @giggio ? https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4

B-Art avatar Nov 18 '23 16:11 B-Art

First I tried via winget. Then via the MSI download. Same result.

giggio avatar Nov 18 '23 16:11 giggio

First I tried via winget. Then via the MSI download. Same result.

Have you tried completely uninstalling the previous MSI first? Not ideal I know, in-place updates should work. Use "Add or Remove programs" to see what is installed, and also check the directory "c:\Program Files\PowerShell\7"

rhubarb-geek-nz avatar Nov 22 '23 08:11 rhubarb-geek-nz

Have you tried completely uninstalling the previous MSI first? Not ideal I know, in-place updates should work. Use "Add or Remove programs" to see what is installed, and also check the directory "c:\Program Files\PowerShell\7"

I have.

I have now also tried installing the Microsoft Store Version, and I get the same error: image

giggio avatar Nov 22 '23 22:11 giggio

Tried now using the global tool, it also does not work:

image

I installed 7.3.10, as it still works. :(

giggio avatar Nov 22 '23 22:11 giggio

Alas, there are enough other problems with 7.4.0 to suggest sticking with 7.3.10 ( for the moment ).

rhubarb-geek-nz avatar Nov 22 '23 22:11 rhubarb-geek-nz

The problem persists at version 7.4.1, released more recently.

image

giggio avatar Jan 25 '24 23:01 giggio

Also, tried using version 7.5 preview from the store, also broken.

image

giggio avatar Jan 25 '24 23:01 giggio

I have tracked the error and added the explanation of why it is happening to the additional context section of the issue.

giggio avatar Mar 13 '24 00:03 giggio

I am also experiencing this issue. I've had to use PSModulePath environment variable within System Properties in the meantime, which is not a perfect workaround.

Alvaka-KThor avatar Apr 04 '24 23:04 Alvaka-KThor

On Linux:

ForEach-Object: /home/vsts/work/_temp/f3a905a8-4984-469a-b3ba-7a9ba49e76af.ps1:5
Line |
   5 |  "whatever" | ForEach-Object -Parallel { $_ }
     |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | An unexpected error has occurred while processing ForEach-Object
     | -Parallel input. This may mean that some of the piped input did not get
     | processed. Error: System.ArgumentOutOfRangeException: Index was out of
     | range. Must be non-negative and less than or equal to the size of the
     | collection. (Parameter 'startIndex')    at System.String.IndexOf(Char
     | value, Int32 startIndex, Int32 count)    at
     | System.Management.Automation.ModuleIntrinsics.UpdatePath(String path,
     | String pathToAdd, Int32& insertIndex)    at
     | System.Management.Automation.ModuleIntrinsics.GetModulePath(String
     | currentProcessModulePath, String hklmMachineModulePath, String
     | hkcuUserModulePath)    at
     | System.Management.Automation.ModuleIntrinsics.SetModulePath()    at
     | System.Management.Automation.ModuleIntrinsics..ctor(ExecutionContext
     | context)    at
     | System.Management.Automation.ExecutionContext.InitializeCommon(AutomationEngine engine, PSHost hostInterface)    at System.Management.Automation.AutomationEngine..ctor(PSHost hostInterface, InitialSessionState iss)    at System.Management.Automation.Runspaces.LocalRunspace.DoOpenHelper()    at System.Management.Automation.Runspaces.RunspaceBase.CoreOpen(Boolean syncCall)    at System.Management.Automation.PSTasks.PSTaskPool.GetRunspace(Int32 taskId)    at System.Management.Automation.PSTasks.PSTaskPool.Add(PSTaskBase task)    at Microsoft.PowerShell.Commands.ForEachObjectCommand.<InitParallelParameterSet>b__67_2(Object _).

On Windows:

"C:\Program Files\PowerShell\7\pwsh.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'D:\a\_temp\86498521-8914-4ea7-ba0c-67b8bb7a6633.ps1'"
The shell cannot be started. A failure occurred during initialization:
Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'startIndex')
##[error]PowerShell exited with code '70'.

Azure DevOps pipeline yaml to reproduce the issue:

jobs:
- job: windows
  pool:
      vmImage: windows-latest
  steps:
  - pwsh: |
      $filePath = Join-Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY "powershellmodules"
      $separator = $isWindows ? ";" : ":"   
      $updatedPSModulePath = $env:PSModulePath, $filePath -join $separator
      $powershellConfigPath = Join-Path $PSHOME 'powershell.config.json'
      if (-not (Test-Path $powershellConfigPath)){
        New-Item -Path $powershellConfigPath -ItemType File -Force
        $config = @{
          PSModulePath = $updatedPSModulePath
        }
      }
      else {
        Write-Verbose "Found existing powershell config, updating PSModulePath"
        $config = Get-Content -Path $powershellConfigPath | ConvertFrom-Json -AsHashtable -Depth 100
        $config["PSModulePath"] = $updatedPSModulePath
      }
      Write-Verbose "Pushing content to $powershellConfigPath" -Verbose
      $config | ConvertTo-Json -Depth 100 | Tee-Object -FilePath $powershellConfigPath
    displayName: Update PSModulePath

  - pwsh: |
      Write-Verbose ('$env:PSModulePath {0}' -f $env:PSModulePath) -Verbose
      "whatever" | ForEach-Object -Parallel { $_ }
    displayName: Debug

- job: linux
  pool:
      vmImage: ubuntu-latest
  steps:
  - pwsh: |
      $filePath = Join-Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY "powershellmodules"
      $separator = $isWindows ? ";" : ":"   
      $updatedPSModulePath = $env:PSModulePath, $filePath -join $separator
      $powershellConfigPath = Join-Path $PSHOME 'powershell.config.json'
      if (-not (Test-Path $powershellConfigPath)){
        New-Item -Path $powershellConfigPath -ItemType File -Force
        $config = @{
          PSModulePath = $updatedPSModulePath
        }
      }
      else {
        Write-Verbose "Found existing powershell config, updating PSModulePath"
        $config = Get-Content -Path $powershellConfigPath | ConvertFrom-Json -AsHashtable -Depth 100
        $config["PSModulePath"] = $updatedPSModulePath
      }
      Write-Verbose "Pushing content to $powershellConfigPath" -Verbose
      $config | ConvertTo-Json -Depth 100 | Tee-Object -FilePath $powershellConfigPath
    displayName: Update PSModulePath

  - pwsh: |
      Write-Verbose ('$env:PSModulePath {0}' -f $env:PSModulePath) -Verbose
      "whatever" | ForEach-Object -Parallel { $_ }
    displayName: Debug

w-boyd avatar May 27 '24 17:05 w-boyd

Any updates?

wboyd-aw avatar Aug 20 '24 22:08 wboyd-aw