Unable to find type when running powershell -command
Asked Answered
L

2

11

I have a PowerShell script which I intend to use as a deployment step in Bamboo. Opening PowerShell and running the script with ./script.ps1 works fine, but using powershell.exe -command ./script.ps1 fails with error Unable to find type [Microsoft.PowerShell.Commands.WebRequestMethod].

What is the difference between running the script directly from PowerShell and by using powershell.exe -command? What am I missing?

MWE for the issue in question:

function Test-RestMethod {
    param([string]$Uri, [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'Get')

    $result = Invoke-RestMethod $uri -Method $Method
    return $result
}

Test-RestMethod -Uri https://blogs.msdn.microsoft.com/powershell/feed/ -Method 'Get' | Format-Table -Property Title, pubDate
Lonnylonslesaunier answered 16/4, 2018 at 8:36 Comment(2)
I would guess your path to powershell is returning a different version, try using Get-Host to determine which version each approach is using.Satiable
They are both using the same versions, on the same architecture (both 64-bit PowerShell v5.1.14393.1198).Lonnylonslesaunier
O
6

To make a type available, if PowerShell does not load it already automatically, just add the corresponding module or assembly manually by using Import-Module or Add-Type. In your case, you have to load an Assembly as can be derived from the docs (Microsoft.PowerShell.Commands.WebRequestMethod):

Add-Type -AssemblyName Microsoft.PowerShell.Commands.Utility
Ocieock answered 4/10, 2021 at 17:26 Comment(0)
W
9

I guess it can be an issue with PowerShell.exe itself, I can reproduce the issue in PowerShell 2.0, 3.0, 4.0 and 5.0.

It's an issue that you can't use type constraint of namespace Microsoft.PowerShell.Commands if you don't run any other command first when you are running your script by using PowerShell.exe

I found two workarounds for you.

a. Run a senseless cmdlet in the beginning of your script, for example

Start-Sleep -Milliseconds 1
function Test-RestMethod {
param([string]$Uri, [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'Get')

$result = Invoke-RestMethod $uri -Method $Method
return $result
}

Test-RestMethod -Uri https://blogs.msdn.microsoft.com/powershell/feed/ -Method 'Get' | Format-Table -Property Title, pubDate

b. Remove the type constraint, it's still working fine

function Test-RestMethod {
param([string]$Uri, $Method = 'Get')

$result = Invoke-RestMethod $uri -Method $Method
return $result
}

Test-RestMethod -Uri https://blogs.msdn.microsoft.com/powershell/feed/ -Method 'Get' | Format-Table -Property Title, pubDate
Wagoner answered 16/4, 2018 at 13:52 Comment(2)
Yes, your workarounds work for me and they helped me find out what the real problem was. Exception was caused by a PowerShell module Microsoft.PowerShell.Utility not being loaded/imported. Running Start-Sleep in your first workaround loads this module quietly, but I don't know why it works this way. I will describe this in another answer.Lonnylonslesaunier
I know this post is old, but I've only just run into this issue recently (using PowerShell 7). Given your logic regarding "lazy loading" of the namespace, then also wrapping the code line that references the enum from the namespace in a Measure-Command block should also work. I'm going to try this as a fix (hack) to see if it works.Sachasachem
O
6

To make a type available, if PowerShell does not load it already automatically, just add the corresponding module or assembly manually by using Import-Module or Add-Type. In your case, you have to load an Assembly as can be derived from the docs (Microsoft.PowerShell.Commands.WebRequestMethod):

Add-Type -AssemblyName Microsoft.PowerShell.Commands.Utility
Ocieock answered 4/10, 2021 at 17:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.