PowerShell / PowerShellGetv2

PowerShellGet is the Package Manager for PowerShell
https://www.PowerShellGallery.com
MIT License
431 stars 138 forks source link

Non-fatal errors from deserialization of PSRepositories.xml #520

Closed ghost closed 2 years ago

ghost commented 5 years ago

Steps to reproduce

The exact conditions which cause the problem to be exhibited are unknown.

PS> Get-InstalledModule PowerShellGet

Many other PowerShellGet cmdlets also exhibit the problem, but Get-InstalledModule is the simplest to demonstrate.

Expected behavior

No exceptions or errors.

Actual behavior

Exception calling "Deserialize" with "1" argument(s): "Current Node type is Text. Expected type is Element. Line 1,
position 81."
At C:\Users\alex.martin\OneDrive - Imagine
One\Documents\WindowsPowerShell\Modules\PowerShellGet\2.2\PSModule.psm1:1132 char:5
+     [System.Management.Automation.PSSerializer]::Deserialize($filecon ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : XmlException

The property 'Keys' cannot be found on this object. Verify that the property exists.
At C:\Users\alex.martin\OneDrive - Imagine
One\Documents\WindowsPowerShell\Modules\PowerShellGet\2.2\PSModule.psm1:6460 char:9
+         $script:PSGetModuleSources.Keys | Microsoft.PowerShell.Core\F ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

You cannot call a method on a null-valued expression.
At C:\Users\alex.martin\OneDrive - Imagine
One\Documents\WindowsPowerShell\Modules\PowerShellGet\2.2\PSModule.psm1:2749 char:8
+     if($script:PSGetModuleSources.Contains($SourceName))
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.1.18362.145
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.18362.145}
BuildVersion                   10.0.18362.145
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
> Get-Module -ListAvailable PowerShellGet,PackageManagement
    Directory: C:\Users\<me>\Documents\WindowsPowerShell\Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.4.3      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Script     2.2        PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCap...

    Directory: C:\Program Files\WindowsPowerShell\Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.4.2      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Binary     1.0.0.1    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-Packa...
Script     1.0.0.1    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module, ...
> Get-PackageProvider -ListAvailable
Name                     Version          DynamicOptions
----                     -------          --------------
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
nuget                    2.8.5.208
NuGet                    3.0.0.1          Destination, ExcludeVersion, Scope, SkipDependencies, Headers, FilterOnTag...
PowerShellGet            2.2.0.0          PackageManagementProvider, Type, Scope, AllowClobber, SkipPublisherCheck, ...
PowerShellGet            1.0.0.1
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent

Resolution attempts

Debugging PowerShellGet using VS Code showed that the error stemmed from attempting to deserialize PSRepositories.xml using [System.Management.Automation.PSSerializer]::Deserialize(), in the function DeSerialize-PSObject. PSRepositories.xml appeared valid to me. I double-checked by deleting it and trying again; the copy that PowerShellGet recreated also exhibited the problem after a PowerShell restart. Replacing DeSerialize-PSObject with an alias to Import-CliXml resolved the problem.

Recommendations

If possible, it might help to detect if Import-CliXml is available and use that instead.

SydneyhSmith commented 5 years ago

@alexbuzzbee thanks for opening this issue and for taking the time to de-bug the issue yourself...one challenge we are having is re-producing this behavior...have you tried uninstalling and re-installing PowerShellGet...also wondering if you are able to successfully use any PowerShellGet commands and if you hit any errors using PackageManagement i.e. is Get-Package PowerShellGet successful? Also when you hit errors using other PowerShellGet cmdlets is it always the same error message?

ghost commented 5 years ago

I've made a number of attempts to upgrade PowerShellGet and PackageManagement to a newer version, and none of them have fixed the problem. I can try Get-Package PowerShellGet tomorrow when I'm at my normal machine.

alerickson commented 5 years ago

@alexbuzzbee has this been happening with different versions of PowerShellGet? Do you have the System.Management.Automation .dll on your machine?

ghost commented 5 years ago

I should probably note that I have PowerShell 6.2 and 7-preview.2 installed alongside 5.1. This problem does not happen in those versions.

Get-Package PowerShellGet works fine. Cmdlets that do not trigger the problem include Get-PSRepository and Save-Module. The same error messages occur with all problematic commands; additionally, with a Get-InstalledModule of all modules, they occur once for every output object.

I don't know how I can safely fully uninstall PowerShellGet without losing the ability to reinstall it, but I have tried upgrades and per-scope (CurrentUser) reinstalls with no effect.

System.Management.Automation.dll exists in the GAC, in WinSxS, in my copy of the PowerShell Reference Assemblies, and in the install directories for PowerShell 6 and 7. The loaded copy is at C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll.

This has been happening for a while now, through several upgrades of PowerShellGet, though I can't tell you for sure what the previous versions were. I think I saw it in 2.1.4 and 2.1.3. The current version I'm using is 2.2 installed in the CurrentUser scope from the PSGallery.

alexvergilis commented 5 years ago

I have this same issue with the 2.2.1 release. Can I provide you with any additional information that can help you address this?

ghost commented 5 years ago

@alexvergilis Compare your system to the information I've put here about mine and list what's the same. Maybe we can narrow down the trigger conditions.

alexvergilis commented 5 years ago
> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.17763.771
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.771
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
> Get-Module -ListAvailable PowerShellGet,PackageManagement

    Directory: C:\Program Files\WindowsPowerShell\Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.4.5      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script     1.4.4      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script     1.4.3      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script     1.4.2      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script     1.4.1      PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Binary     1.0.0.1    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script     2.2.1      PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}
Script     2.2        PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}
Script     2.1.5      PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}
Script     2.1.4      PowerShellGet                       {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}
Script     1.0.0.1    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}
> Get-PackageProvider -ListAvailable

Name                     Version          DynamicOptions
----                     -------          --------------
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
nuget                    2.8.5.208
NuGet                    3.0.0.1          Destination, ExcludeVersion, Scope, SkipDependencies, Headers, FilterOnTag, Contains, AllowPrereleaseVersions, ConfigFile, SkipValidate
PowerShellGet            2.2.1.0          PackageManagementProvider, Type, Scope, AllowClobber, SkipPublisherCheck, InstallUpdate, NoPathUpdate, AllowPrereleaseVersions, Filter, Tag, Includes, DscResource, R...
PowerShellGet            2.2.0.0
PowerShellGet            2.1.5.0
PowerShellGet            2.1.4.0
PowerShellGet            1.0.0.1
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent
alerickson commented 4 years ago

@alexvergilis @alexbuzzbee could you both let me know which dlls you have loaded when you're encountering this issue ([System.AppDomain]::CurrentDomain.GetAssemblies())

ghost commented 4 years ago

@alerickson Several previously-unloaded assemblies were loaded when I ran Get-InstalledModule PowerShellGet. I decided that the output from the default table format was not sufficient, so I piped the data to Format-List, which produced too much text to be reasonably included here. As such, I have put the output on Pastebin. If any filtering or further information is desired, I still have the ability to reproduce at will.

alexvergilis commented 4 years ago

My problem actually went away after the following:

sfc /scannow System restart Uninstall-Module -Name ModuleNameThatProducedTheErrorBefore -AllVersions -Force

Install-Module -Name ModuleNameThatProducedTheErrorBefore

ghost commented 4 years ago

Interesting. I've run sfc /scannow without seeing any improvement. I'll try the whole set, but I'm not confident that it'll work.

Nevember commented 2 years ago

Hi! After a couple years of dealing with this frustrating issue, I've finally found a way to reliably repro this XmlException, PropertyNotFoundStrict, and InvokeMethodOnNull error combo.

The issue (at least in my case) was that--deep within my lengthy profile.ps1, I'd set the preference variable $OFS to ","; the issue seemingly occurs if the value for $OFS includes any non-whitespace characters.

The following code block easy allows for reproducing the error (tested environments are listed at the bottom).

# (Optional) Remove all modules for clean testing.
Remove-Module * -Force

# For easy console differentiation, we'll use verbose output for our $OFS value.
Write-Verbose -Verbose "`$OFS is `'$OFS`'."

# Search using Find-Module, thus importing PowerShellGet (PSG); this search currently returns 3 items, and will not fail since the default value of $OFS is currently set.
Find-Module Github.G*

# Change the value of $OFS to ', '
$OFS = ', '
Write-Verbose -Verbose "`$OFS is `'$OFS`'."

# Search again using Find-Module; this command also will not fail. Though the value of $OFS has been changed, the exception doesn't occur because PSG is already imported.
Find-Module Github.G*

# Remove the PSG module.
Remove-Module PowerShellGet
Write-Verbose -Verbose "`$OFS is `'$OFS`'."

# Search again using Find-Module, thus (re-)importing PSG. The XmlException, PropertyNotFoundStrict, and InvokeMethodOnNull errors now occur.
Find-Module Github.G*

# To clear the error state, remove the PSG module, change the value of $OFS to empty or whitespace, then search again.
Remove-Module PowerShellGet, PackageManagement; $OFS = " `n`r`t"; Write-Verbose -Verbose "`$OFS is `'$OFS`'."; Find-Module Github.G*

# Personally, I switch error view to "category" for easy viewing on subsequent tests if I already know what the errors are going to be:
$ErrorView = 'CategoryView'

# To test other characters/strings, simply run the above line again, but change the value of $OFS to other characters/strings, e.g.:
Remove-Module PowerShellGet; $OFS = " # ";Write-Verbose -Verbose "`$OFS is `'$OFS`'."; Find-Module Github.G*

In my tests, failing values included the following characters, both with and without preceding/trailing whitespace: ,;."'][ The space character, 0x20, alone did not fail; other characters that didn't fail, even when used together: tr`n

I've successfully repro-ed the issue in the following environments: • Up-to-date Windows 10 and Windows 11 production environments, using Windows PS 5.1 (including the ISE) and PS 7.2.6 (side-by-side) with PowerShellGet 2.2.5 and PackageManagement 1.4.8.1. • Ubuntu 22.04 using WSL, PowerShell 7.2.6, and PowerShellGet versions 2.2.5 and 3.0.17 (pre) • Windows PowerShell 5.1 in Windows (11) Sandbox (install the NuGet package provider prior to running the above code). Interestingly, in the Windows 11 sandbox, the only version of PSG was the default module/script, version 1.0.01.

For now, my workaround is simply leaving the $OFS variable at its default value. If there's anything else I can provide that'll help with this, please let me know.

alerickson commented 2 years ago

@Nevember thanks for the detailed repro information! Were you able to try the repro with 3.0.17-beta17 in Windows 10 and Windows 11?

Nevember commented 2 years ago

@alerickson, my pleasure!

I have to apologize for one detail, though: The issue does not occur with 3.0.17-beta17 in Ubuntu. I had forgotten that the command Find-Module has been replaced with Find-PSResource in newer versions of PowerShellGet, so when tested in Ubuntu yesterday, v2.2.5 was imported, not beta17.

I discovered this when testing in Win10 and Win11 (and Server2019) a few minutes ago. When using Find-PSResource from version 3.0.17-beta17, the error didn't occur in any test environment. I tried using comma, semicolon, and pound symbols.

Since the other reporters mentioned Get-InstalledModule, I found that it, too, suffers from the same $OFS issue with PowerShellGet v1.0.0.1 and v2.2.5; however, I don't see an equivalent command in v3.0.17-beta17, unless it's simply Get-Module -ListAvailable from Microsoft.PowerShell.Core, which doesn't seem to suffer from this issue.

By using Set-Alias Find-Module PowerShellGet\Find-PSResource -Force and making sure the only PSG version being imported was 3.0.17-beta17, I was able to successfully run Find-Module Github.G* with $OFS set to ', ' without any issues. 💯

anamnavi commented 2 years ago

@Nevember thank you for this feedback, this is great to hear that this is not reproducing in v3.0.17-beta17, yay! The equivalent command for Get-InstalledModule is Get-PSResource in PowerShellGet V3. If the $OFS issue occurs with the Get-PSResource cmdlet please let us know, thank you!

Closing this issue as we're not working on PowerShellGetV2. If you're still facing it while using PowerShellGetV3 please feel free to comment and we'll re-open.

ghost commented 2 years ago

This issue is not fixed by PowerShellGet v3 until it is generally available. While PowerShellGet v3 is still in preview, PowerShellGet v2 remains the production version.