5

Environment details:

  • x64 Win7 SP1 Enterprise
  • Windows PowerShell v5.0

Without any profiles loaded, my local sessions are returning

Not enough memory.

when I try to execute help or man. This occurs whether I'm using the native powershell.exe or .

Strangely, I am able to execute any other aliases I've tried, and it doesn't add to the $Error variable, so I have no idea where to start troubleshooting (I've tried -ErrorAction Stop and $ErrorActionPreference = 'Stop').

As a footnote, I don't have any elevated privileges.


After some exploration, I found that man is actually an alias for help which isn't an alias for Get-Help, but a function of its own with this definition:

function help {
<#
.FORWARDHELPTARGETNAME Get-Help
.FORWARDHELPCATEGORY Cmdlet
#>
    [CmdletBinding(DefaultParameterSetName = 'AllUsersView', HelpUri = 'http://go.microsoft.com/fwlink/?LinkID=113316')]
    param(
        [Parameter(Position = 0, ValueFromPipelineByPropertyName = $true)]
        [string]
        ${Name},

        [string]
        ${Path},

        [ValidateSet('Alias', 'Cmdlet', 'Provider', 'General', 'FAQ', 'Glossary', 'HelpFile', 'ScriptCommand', 'Function', 'Filter', 'ExternalScript', 'All', 'DefaultHelp', 'Workflow', 'DscResource', 'Class', 'Configuration')]
        [string[]]
        ${Category},

        [string[]]
        ${Component},

        [string[]]
        ${Functionality},

        [string[]]
        ${Role},

        [Parameter(ParameterSetName = 'DetailedView', Mandatory = $true)]
        [switch]
        ${Detailed},

        [Parameter(ParameterSetName = 'AllUsersView')]
        [switch]
        ${Full},

        [Parameter(ParameterSetName = 'Examples', Mandatory = $true)]
        [switch]
        ${Examples},

        [Parameter(ParameterSetName = 'Parameters', Mandatory = $true)]
        [string]
        ${Parameter},

        [Parameter(ParameterSetName = 'Online', Mandatory = $true)]
        [switch]
        ${Online},

        [Parameter(ParameterSetName = 'ShowWindow', Mandatory = $true)]
        [switch]
        ${ShowWindow}
    )

    #Set the outputencoding to Console::OutputEncoding. More.com doesn't work well with Unicode.
    $outputEncoding = [System.Console]::OutputEncoding

    Get-Help @PSBoundParameters | more
}

Even further... more is another function:

function more {
    param([string[]]$paths)

    $OutputEncoding = [System.Console]::OutputEncoding

    if($paths) {
        foreach ($file in $paths) {
            Get-Content $file | more.com
        }
    }
    else {
        $input | more.com
    }
}
Maximilian Burszley
  • 18,243
  • 4
  • 34
  • 63
  • Just to confirm, it's only the `help` and `man` commands and `more.com` executable that cause the "Not enough memory" error? PowerShell otherwise works normally? – Lance U. Matthews Mar 19 '19 at 19:38
  • @BACON Correct. After some additional investigation, it looks to be an encoding issue with `more.com` which persists as long as that console host lives since I changed it to [tag:utf-8] and it doesn't handle multi-byte characters. I'm going to post a write-up to answer this question. – Maximilian Burszley Mar 19 '19 at 19:40

1 Answers1

5

A seemingly inherent flaw with more.com, it has difficulty handling multi-byte encodings (such as ) and will instead throw a

Not enough memory.

error.

I don't have enough knowledge to figure out why it throws that message or how to replicate it on different systems (for example, I could not replicate on x64 Windows 10 1804 Pro), but it can be remediated by changing the OutputEncoding static member on [System.Console] to a default encoding (in this case, CP437, which was my conhost's default):

[System.Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(437)

or other single-byte encoding, such as CP1252.

If this error is being observed in , it can be remediated using chcp.com (untested whether this also updates [Console]::OutputEncoding):

chcp.com 437

As a side-note, the code that caused this failure for me is in my $PROFILE:

[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.UTF8Encoding]::new()

The issues persisted while using the same console host, even after exiting when I was left in a prompt.


Edit: for powershell to work, I had to do a combined codepage + OutputEncoding change:

[Console]::OutputEncoding = [Text.Encoding]::GetEncoding(437)
& chcp.com 437
Maximilian Burszley
  • 18,243
  • 4
  • 34
  • 63
  • This is extremely helpful! FWIW, if you install [MSYS2](https://www.msys2.org/) and make its executable available on the PowerShell PATH, you can use `Get-Help ... | less`, which allows scrolling up and down. (Then, type `q` to quit, or `h` for options; navigation info is always shown at the bottom.) [Less](https://manpage.me/?q=less) is more! ;-) – jpaugh Jun 25 '19 at 15:30