9

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
ryszka.dev
  • 126
  • 1
  • 8
  • I would guess your path to powershell is returning a different version, try using Get-Host to determine which version each approach is using. – David Martin Apr 16 '18 at 10:47
  • They are both using the same versions, on the same architecture (both 64-bit PowerShell v5.1.14393.1198). – ryszka.dev Apr 17 '18 at 09:55

2 Answers2

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
Dong Mao
  • 361
  • 1
  • 6
  • 4
    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. – ryszka.dev Apr 17 '18 at 10:02
  • 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. – Glen Oct 29 '20 at 15:36
3

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
stackprotector
  • 10,498
  • 4
  • 35
  • 64