PoshCode Logo PowerShell Code Repository

HttpRest 1.2 (modification of post by Joel Bennett view diff)
View followups from Joel Bennett | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1262"></script>download | new post

Some enhancements to HttpRest to support posting content, and a couple other things I needed for OAuth support…

OLD documentation on this post on HuddledMasses (I’ll be writing a new post soon to detail this OAuth stuff, which will include some coverage of this, and at least one more release with some man/help for the HttpRest functions.

  1. #requires -version 2.0
  2. ## HttpRest module version 1.2
  3. ####################################################################################################
  4. ## Still only the initial stages of converting to a full v2 module
  5. ## Based on the REST api from MindTouch's Dream SDK
  6. ##
  7. ## INSTALL:
  8. ## You need mindtouch.dream.dll (mindtouch.core.dll, SgmlReaderDll.dll, log4net.dll) from the SDK
  9. ## Get MindTouch_Dream_1.6.0.zip or greater from http`://sourceforge.net/projects/dekiwiki/files/
  10. ## Unpack it, and you can find these dlls in the "dist" folder.
  11. ## Make sure to put them in the folder with this script module.
  12. ##
  13. ## For documentation of Dream:  http`://wiki.developer.mindtouch.com/Dream
  14. ####################################################################################################
  15. ## Version History
  16. ## 1.0   First Release
  17. ## 1.0.1 Added Get-WebPageContent
  18. ## 1.0.2 Bug fix for Invoke-Http credential issues
  19. ## 1.1.0 First release of a PowerShell 2.0 (CTP3/Windows7) version....
  20. ## 1.1.1 Added Get-WebPageText and Get-Webfile ... cleaned up options
  21. ## 1.2   Added Hashtable parsing on Get-DreamMessage
  22. ##       Fixed parsing on Get-DreamPlug so we don't get errors on PowerShell 2
  23. ##       Added ParameterSet on Invoke-Http to pass in a plug directly (easier to debug)
  24. ####################################################################################################
  25. ## Usage:
  26. ##   function Get-Google {
  27. ##     Invoke-Http GET http`://www.google.com/search @{q=$args} |
  28. ##       Receive-Http Xml "//h3[@class='r']/a" | Select href, InnerText
  29. ##   }
  30. ##   #########################################################################
  31. ##   function Get-WebFile($url,$cred) {
  32. ##     Invoke-Http GET $url -auth $cred | Receive-Http File
  33. ##   }
  34. ##   #########################################################################
  35. ##   function Send-Paste {
  36. ##   PARAM($PastebinURI="http`://posh.jaykul.com/p/",[IO.FileInfo]$file)
  37. ##   PROCESS {
  38. ##     if($_){[IO.FileInfo]$file=$_}
  39. ##
  40. ##     if($file.Exists) {
  41. ##       $ofs="`n"
  42. ##       $result = Invoke-Http POST $PastebinURI @{
  43. ##         format="posh"           # PowerShell
  44. ##         expiry="d"              # (d)ay or (m)onth or (f)orever
  45. ##         poster=$([Security.Principal.WindowsIdentity]::GetCurrent().Name.Split("\")[-1])
  46. ##         code2="$((gc $file) -replace "http`://","http``://")" # To get past the spam filter.
  47. ##         paste="Send"
  48. ##       } -Type FORM_URLENCODED -Wait
  49. ##       $xml = $result.AsDocument().ToXml()
  50. ##       write-output $xml.SelectSingleNode("//*[@class='highlight']/*").href
  51. ##     } else { throw "File Not Found" }
  52. ##   }}
  53. ##
  54. ####################################################################################################
  55. if(!$PSScriptRoot){
  56.    Write-Debug $($MyInvocation.MyCommand | out-string)
  57.    $PSScriptRoot=(Split-Path $MyInvocation.MyCommand.Path -Parent)
  58. }
  59. #  Write-Debug "Invocation: $($MyInvocation.MyCommand.Path)"
  60. #  Write-Debug "Invocation: $($MyInvocation.MyCommand)"
  61. #  Write-Debug "Invocation: $($MyInvocation)"
  62.  
  63. Write-Debug "PSScriptRoot: '$PSScriptRoot'"
  64.  
  65.  
  66. # This Module depends on MindTouch.Dream
  67. $null = [Reflection.Assembly]::LoadFrom( "$PSScriptRoot\mindtouch.dream.dll" )
  68. # MindTouch.Dream requires: mindtouch.dream.dll, mindtouch.core.dll, SgmlReaderDll.dll, and log4net.dll)
  69. # This Module also depends on utility functions from System.Web
  70. $null = [Reflection.Assembly]::LoadWithPartialName("System.Web")
  71.  
  72. ## Some utility functions are defined at the bottom
  73. [uri]$global:url = ""
  74. [System.Management.Automation.PSCredential]$global:HttpRestCredential = $null
  75.  
  76. function Get-DreamMessage($Content,$Type) {
  77.    #Write-Verbose "Content: $(if($Content){$Content.GetType()}else{"null"}) $($Content.Length) and Type: $(if($Type){$Type.GetType()}else{"null"})"
  78.    if(!$Content) {
  79.       Write-Verbose "No Content"
  80.       return [MindTouch.Dream.DreamMessage]::Ok()
  81.    }
  82.    if( $Content -is [System.Xml.XmlDocument]) {
  83.       Write-Verbose "Xml Content"
  84.       return [MindTouch.Dream.DreamMessage]::Ok( $Content )
  85.    }
  86.    if($Content -is [Hashtable]) {
  87.       $kvp = $Content.GetEnumerator() | %{ new-object "System.Collections.Generic.KeyValuePair[[String],[String]]" $_.Key, $_.Value }
  88.       Write-Verbose "Hashtable content: $($kvp | ft -auto | out-string -stream | %{ "   $_ ".TrimEnd()} )"
  89.       return [MindTouch.Dream.DreamMessage]::Ok( $kvp )
  90.    }
  91.    
  92.    if(Test-Path $Content -EA "SilentlyContinue") {
  93.       Write-Verbose "File Content"
  94.       return [MindTouch.Dream.DreamMessage]::FromFile((Convert-Path (Resolve-Path $Content)));
  95.    }
  96.    if($Type -is [String]) {
  97.       Write-Verbose "Specific Content: $([MindTouch.Dream.MimeType]::$Type)"
  98.       $Type = [MindTouch.Dream.MimeType]::$Type
  99.    }
  100.    if($Type -is [MindTouch.Dream.DreamMessage]) {
  101.       Write-Verbose "Specific Content: $([MindTouch.Dream.MimeType]::$Type)"
  102.       return [MindTouch.Dream.DreamMessage]::Ok( $Type, $Content )
  103.    } else {  
  104.       Write-Verbose "Unspecified string content"
  105.       return [MindTouch.Dream.DreamMessage]::Ok( $([MindTouch.Dream.MimeType]::TEXT), $Content )
  106.    }
  107. }
  108.  
  109. function Get-DreamPlug {
  110.    [CmdletBinding()]
  111.    PARAM ( $Url, [hashtable]$With, [hashtable]$Headers )
  112.    if($Url -is [array]) {
  113.       Write-Verbose "URL is an array of parts"
  114.       if($Url[0] -is [hashtable]) {
  115.          Write-Verbose "URL is an array of hashtable parts"
  116.          $plug = [MindTouch.Dream.Plug]::New($global:url)
  117.          foreach($param in $url.GetEnumerator()) {
  118.             if($param.Value) {
  119.                $plug = $plug.At($param.Key,"=$(Encode-Twice $param.Value)")
  120.             } else {
  121.                $plug = $plug.At($param.Key)
  122.             }
  123.          }
  124.       }
  125.       else
  126.       {
  127.          [URI]$uri = Join-Url $global:url $url
  128.          $plug = [MindTouch.Dream.Plug]::New($uri)
  129.       }
  130.    }
  131.    elseif($url -is [string])
  132.    {
  133.       Write-Verbose "String URL"
  134.       trap { continue }
  135.       [URI]$uri = $url
  136.       if(!$uri.IsAbsoluteUri) {
  137.          $uri = Join-Url $global:url $url
  138.          Write-Verbose "Relative URL, appending to $($global:url) to get: $uri"
  139.       }
  140.       $plug = [MindTouch.Dream.Plug]::New($uri)
  141.    }
  142.    else {
  143.       Write-Verbose "No URL, using default $($global:url)"
  144.       $plug = [MindTouch.Dream.Plug]::New($global:url)
  145.    }
  146.    if($with) {
  147.       foreach($w in $with.GetEnumerator()) {
  148.          if($w.Value) {
  149.             $plug = $plug.With($w.Key,$w.Value)
  150.          }
  151.       }
  152.       Write-Verbose "Added 'with' params: $plug"
  153.    }
  154.    if($headers) {
  155.       foreach($header in $Headers.GetEnumerator()) {
  156.          if($header.Value) {
  157.             $plug = $plug.WithHeader($header.Key,$header.Value)
  158.          }
  159.       }
  160.       Write-Verbose "Added 'with' params: $plug"
  161.    }
  162.    return $plug
  163. }
  164.  
  165. #CMDLET Receive-Http {
  166. Function Receive-Http {
  167. PARAM(
  168.    #  [Parameter(Position=1, Mandatory=$false)]
  169.    #  [ValidateSet("Xml", "File", "Text","Bytes")]
  170.    #  [Alias("As")]
  171.    $Output = "Xml"
  172. ,
  173.    #  [Parameter(Position=2, Mandatory=$false)]
  174.    [string]$Path
  175. ,
  176.    #  [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Result")]
  177.    #  [Alias("IO")]
  178.    #  [MindTouch.Dream.Result``1[[MindTouch.Dream.DreamMessage]]]
  179.    $InputObject
  180. #,
  181.    #  [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Response")]
  182.    #  [MindTouch.Dream.DreamMessage]
  183.    #  $response
  184. )
  185. BEGIN {
  186.    if($InputObject) {
  187.       Write-Output $inputObject | Receive-Http $Output $Path
  188.    } # else they'd better pass it in on the pipeline ...
  189. }
  190. PROCESS {
  191.    $response = $null
  192.    if($_ -is [MindTouch.Dream.Result``1[[MindTouch.Dream.DreamMessage]]]) {
  193.       $response = $_.Wait()
  194.    } elseif($_ -is [MindTouch.Dream.DreamMessage]) {
  195.       $response = $_
  196.    } elseif($_) {
  197.       throw "We can only pipeline [MindTouch.Dream.DreamMessage] objects, or [MindTouch.Dream.Result`1[DreamMessage]] objects"
  198.    }
  199.    
  200.    if($response) {
  201.       Write-Debug $($response | Out-String)
  202.       if(!$response.IsSuccessful) {
  203.          Write-Error $($response | Out-String)
  204.          Write-Verbose $response.AsText()
  205.          throw "ERROR: '$($response.Status)' Response Status."
  206.       } else {  
  207.          switch($Output) {
  208.             "File" {
  209.                ## Joel's magic filename guesser ...
  210.                if(!$Path) {
  211.                   [string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $response.Headers["Content-Disposition"] ).Groups[1].Value
  212.                   $Path = $fileName.trim("\/""'")
  213.                   if(!$Path){
  214.                      if($response.ResponseUri)  {
  215.                         $fileName = $response.ResponseUri.Segments[-1]
  216.                         $Path = $fileName.trim("\/")
  217.                         if(!([IO.FileInfo]$Path).Extension) {
  218.                            $Path = $Path + "." + $response.ContentType.Split(";")[0].Split("/")[1]
  219.                         }
  220.                      }
  221.                   }
  222.                }
  223.                if($Path) {
  224.                   $File = Get-FileName $Path
  225.                } else {
  226.                   $File = Get-FileName
  227.                }
  228.                $null = [StreamUtil]::CopyToFile( $response.AsStream(), $response.ContentLength, $File )
  229.                Get-ChildItem $File
  230.             }
  231.             "XDoc" {
  232.                if($Path) {
  233.                   $response.AsDocument()[$Path]
  234.                } else {
  235.                   $response.AsDocument()#.ToXml()
  236.                }
  237.             }
  238.             "Xml" {
  239.                if($Path) {
  240.                   $response.AsDocument().ToXml().SelectNodes($Path)
  241.                } else {
  242.                   $response.AsDocument().ToXml()
  243.                }
  244.             }
  245.             "Text" {
  246.                if($Path) {
  247.                   $response.AsDocument()[$Path] | % { $_.AsInnerText }
  248.                } else {
  249.                   $response.AsText()
  250.                }
  251.             }
  252.             "Bytes" {
  253.                $response.AsBytes()
  254.             }
  255.          }
  256.       }
  257.    }
  258. }
  259. }
  260. ## http`://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
  261. ## Nobody actually uses HEAD or OPTIONS, right?
  262. ## And nobody's even heard of TRACE or CONNECT ;)
  263.  
  264. # CMDLET Invoke-Http {
  265. Function Invoke-Http {
  266. [CmdletBinding(DefaultParameterSetName="ByPath")]
  267. PARAM(
  268.    [Parameter(Position=0, Mandatory=$false)]
  269.    [ValidateSet("POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS")] ## There are other verbs, but we need a list to make sure you don't screw up
  270.    [string]$Verb = "GET"
  271. ,
  272.    [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="WithPlug")]
  273.    [MindTouch.Dream.Plug]
  274.    $Plug
  275. ,
  276.    [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="ByPath")]
  277.    [string]
  278.    $Path
  279. ,
  280.    [Parameter(Position=2, Mandatory=$false, ParameterSetName="ByPath")]
  281.    [hashtable]$With
  282. ,
  283.    [Parameter(Position=3, Mandatory=$false, ParameterSetName="ByPath")]
  284.    [hashtable]$Headers
  285. ,
  286.    [Parameter(Mandatory=$false)]
  287.    $Content
  288. ,
  289.    [Parameter(Mandatory=$false)]
  290.    $Cookies
  291. ,
  292.    [Parameter(Mandatory=$false)]
  293.    $Type # Of Content
  294. ,
  295.    [Parameter(Mandatory=$false)]
  296.    [switch]$authenticate
  297. ,
  298.    [Parameter(Mandatory=$false)]
  299.    $credentials
  300. ,
  301.    [Parameter(Mandatory=$false)]
  302.    [switch]$Persistent  ## Note this ALSO causes WaitForResponse
  303. ,
  304.    [switch]$waitForResponse
  305. )
  306. PROCESS {
  307.       if(!$Plug){ #$PSCmdlet.ParameterSetName -eq $ByPath) {
  308.          $Plug = Get-DreamPlug $Path $With $Headers
  309.       }
  310.  
  311.       ## Special Handling for FORM_URLENCODED
  312.       if($Type -like "Form*" -and !$Content) {
  313.          $dream = [MindTouch.Dream.DreamMessage]::Ok( $Plug.Uri )
  314.          $Plug = [MindTouch.Dream.Plug]::New( $Plug.Uri.SchemeHostPortPath )
  315.          Write-Verbose "RECREATED Plug: $($Plug.Uri.SchemeHostPortPath)"
  316.       } else {
  317.          $dream = Get-DreamMessage $Content $Type
  318.          Write-Verbose "Created Dream with Content: $($dream.AsText() |out-String)"
  319.       }
  320.      
  321.       if(!$plug -or !$dream) {
  322.          throw "Can't come up with a request!"
  323.       }
  324.      
  325.       if($Persistent -and $global:HttpRestCookies) {
  326.          $dream.Cookies.Add( $global:HttpRestCookies )
  327.       }
  328.       if($Cookies) {
  329.          $dream.Cookies.Add( $Cookies )
  330.       }
  331.      
  332.       if($authenticate -or $credentials){
  333.          if($credentials -is [System.Management.Automation.PSCredential]) {
  334.             Write-Verbose "AUTHENTICATING AS $($credentials.GetNetworkCredential().UserName)"
  335.             $plug = $plug.WithCredentials($credentials.GetNetworkCredential())
  336.          } elseif($credentials -is [System.Net.ICredentials]) {
  337.             Write-Verbose "AUTHENTICATING AS $($credentials.GetNetworkCredential().UserName)"
  338.             $plug = $plug.WithCredentials($credentials.GetNetworkCredential())
  339.          } else {
  340.             if($credentials) {
  341.                Write-Error "Credential must be a PSCredential or a System.Net.ICredentials"
  342.             }
  343.             $null = Get-HttpCredential  # Make sure they have global credentials
  344.             Write-Verbose "AUTHENTICATING AS $($global:HttpRestCredential.UserName)"
  345.             $plug = $plug.WithCredentials($global:HttpRestCredential.GetNetworkCredential())
  346.          }
  347.       }
  348.      
  349.       Write-Verbose $plug.Uri
  350.      
  351.       ## DEBUG:
  352.       Write-Debug "URI: $($Plug.Uri)"
  353.       Write-Debug "Verb: $($Verb.ToUpper())"
  354.       Write-Debug $($dream | gm | Out-String)
  355.      
  356.       $result = $plug.InvokeAsync( $Verb.ToUpper(),  $dream )
  357.      
  358.       Write-Debug $($result | Out-String)
  359.       #  if($DebugPreference -eq "Continue") {
  360.       #     Write-Debug $($result.Wait() | Out-String)
  361.       #  }
  362.      
  363.       if($waitForResponse -or $Persistent) {
  364.          $result = $result.Wait()
  365.          $global:HttpRestCookies = $result.Cookies
  366.       }
  367.      
  368.       write-output $result
  369.    
  370.       trap [MindTouch.Dream.DreamResponseException] {
  371.          Write-Error @"
  372. TRAPPED DreamResponseException
  373.      
  374. $($_.Exception.Response | Out-String)
  375.  
  376. $($_.Exception.Response.Headers | Out-String)
  377. "@
  378.          break;
  379.       }
  380. }
  381. }
  382.  
  383.  
  384. function Get-WebPageContent {
  385. [CmdletBinding()]
  386. param(
  387.    [Parameter(Position=0,Mandatory=$true)]
  388.    [string]$url
  389. ,
  390.    [Parameter(Position=1,Mandatory=$false)]
  391.    [string]$xpath=""
  392. ,
  393.    [Parameter(Position=2,Mandatory=$false)]
  394.    [hashtable]$with=@{}
  395. ,
  396.    [Parameter(Mandatory=$false)]
  397.    [switch]$Persist
  398. ,
  399.    [Parameter(Mandatory=$false)]
  400.    [switch]$Authenticate
  401. )
  402. BEGIN { $out = "Text"; if($Xml) { $out="Xml" } }
  403. PROCESS {
  404.    invoke-http get $url $with -Authenticate:$Authenticate -Persist:$Persist | receive-http xml $xpath
  405. }
  406. }
  407.  
  408. function Get-WebPageText {
  409. [CmdletBinding()]
  410. param(
  411.    [Parameter(Position=0,Mandatory=$true)]
  412.    [string]$url
  413. ,
  414.    [Parameter(Position=1,Mandatory=$false)]
  415.    [string]$xpath=""
  416. ,
  417.    [Parameter(Position=2,Mandatory=$false)]
  418.    [hashtable]$with=@{}
  419. ,
  420.    [Parameter(Mandatory=$false)]
  421.    [switch]$Persist
  422. ,
  423.    [Parameter(Mandatory=$false)]
  424.    [switch]$Authenticate
  425. )
  426. BEGIN { $out = "Text"; if($Xml) { $out="Xml" } }
  427. PROCESS {
  428.    invoke-http get $url $with -Authenticate:$Authenticate -Persist:$Persist | receive-http text $xpath
  429. }
  430. }
  431.  
  432. function Get-WebFile {
  433. [CmdletBinding()]
  434. param(
  435.    [Parameter(Position=0,Mandatory=$true)]
  436.    [string]$url
  437. ,
  438.    [Parameter(Position=1,Mandatory=$false)]
  439.    [string]$path=""
  440. ,
  441.    [Parameter(Position=2,Mandatory=$false)]
  442.    [hashtable]$with=@{}
  443. ,
  444.    [Parameter(Mandatory=$false)]
  445.    [switch]$Persist
  446. ,
  447.    [Parameter(Mandatory=$false)]
  448.    [switch]$Authenticate
  449. )
  450. PROCESS {
  451.    Invoke-Http GET $url $with -Authenticate:$Authenticate -Persist:$Persist | Receive-Http File $path
  452. }
  453. }
  454.  
  455.  
  456. new-alias gwpc Get-WebPageContent -EA "SilentlyContinue"
  457. new-alias http Invoke-Http        -EA "SilentlyContinue"
  458. new-alias rcv  Receive-Http       -EA "SilentlyContinue"
  459.  
  460.  
  461. # function Get-Http { return Invoke-Http "GET" @args }
  462. # function New-Http { return Invoke-Http "PUT" @args }
  463. # function Update-Http { return Invoke-Http "POST" @args }
  464. # function Remove-Http { return Invoke-Http "DELETE" @args }
  465. # new-alias Set-Http Update-Http
  466. # new-alias Put-Http New-Http
  467. # new-alias Post-Http Update-Http
  468. # new-alias Delete-Http Remove-Http
  469.  
  470. function Set-HttpDefaultUrl {
  471. PARAM ([uri]$baseUri=$(Read-Host "Please enter the base Uri for your RESTful web-service"))
  472.    $global:url = $baseUri
  473. }
  474.  
  475. function Set-HttpCredential {
  476.    param($Credential=$(Get-CredentialBetter -Title   "Http Authentication Request - $($global:url.Host)" `
  477.                                       -Message "Your login for $($global:url.Host)" `
  478.                                       -Domain  $($global:url.Host)) )
  479.    if($Credential -is [System.Management.Automation.PSCredential]) {
  480.       $global:HttpRestCredential = $Credential
  481.    } elseif($Credential -is [System.Net.NetworkCredential]) {
  482.       $global:HttpRestCredential = new-object System.Management.Automation.PSCredential $Credential.UserName, $(ConvertTo-SecureString $credential.Password)
  483.    }
  484. }
  485.  
  486. function Get-HttpCredential {
  487.    if(!$global:url) { Set-HttpDefaultUrl }
  488.    if(!$global:HttpRestCredential) { Set-HttpCredential }
  489.    if(!$Secure) {
  490.       return $global:HttpRestCredential.GetNetworkCredential();
  491.    } else {
  492.       return $global:HttpRestCredential
  493.    }
  494. }
  495.  
  496. # function Authenticate-Http {
  497. # PARAM($URL=@("users","authenticate"), $Credential = $(Get-HttpCredential))
  498. #   $plug = [MindTouch.Dream.Plug]::New( $global:url )
  499. #   $null = $plug.At("users", "authenticate").WithCredentials( $auth.UserName, $auth.Password ).Get()
  500. # }
  501.  
  502.  
  503. function ConvertTo-UrlDoubleEncode {
  504.    param([string]$text)
  505.    return [System.Web.HttpUtility]::UrlEncode( [System.Web.HttpUtility]::UrlEncode( $text ) )
  506. }
  507. New-Alias Encode-Twice ConvertTo-UrlDoubleEncode
  508.  
  509. function Join-Url ( [uri]$baseUri=$global:url ) {
  510.    $ofs="/";$BaseUrl = ""
  511.    if($BaseUri -and $baseUri.AbsoluteUri) {
  512.       $BaseUrl = "$($baseUri.AbsoluteUri.Trim('/'))/"
  513.    }
  514.    return [URI]"$BaseUrl$([string]::join("/",@($args)).TrimStart('/'))"
  515. }
  516.  
  517. function ConvertTo-SecureString {
  518. Param([string]$input)
  519.    $result = new-object System.Security.SecureString
  520.  
  521.    foreach($c in $input.ToCharArray()) {
  522.       $result.AppendChar($c)
  523.    }
  524.    $result.MakeReadOnly()
  525.    return $result
  526. }
  527.  
  528. ## Unit-Test Get-FileName  ## Should return TRUE
  529. ##   (Get-FileName C:\Windows\System32\Notepad.exe)               -eq "C:\Windows\System32\Notepad.exe"   -and
  530. ##   (Get-FileName C:\Windows\Notepad.exe C:\Windows\System32\)   -eq "C:\Windows\System32\Notepad.exe"   -and
  531. ##   (Get-FileName WaitFor.exe C:\Windows\System32\WaitForIt.exe) -eq "C:\Windows\System32\WaitForIt.exe" -and
  532. ##   (Get-FileName -Path C:\Windows\System32\WaitForIt.exe)       -eq "C:\Windows\System32\WaitForIt.exe"      
  533. function Get-FileName {
  534.    param($fileName=$([IO.Path]::GetRandomFileName()), $path)
  535.    $fileName = $fileName.trim("\/""'")
  536.    ## if the $Path has a file name, and it's folder exists:
  537.    if($Path -and !(Test-Path $Path -Type Container) -and (Test-Path (Split-Path $path) -Type Container)) {
  538.       $path
  539.    ## if the $Path is just a folder (and it exists)
  540.    } elseif($Path -and (Test-Path $path -Type Container)) {
  541.       $fileName = Split-Path $fileName -leaf
  542.       Join-Path $path $fileName
  543.    ## If there's no valid $Path, and the $FileName has a folder...
  544.    } elseif((Split-Path $fileName) -and (Test-Path (Split-Path $fileName))) {
  545.       $fileName
  546.    } else {
  547.       Join-Path (Get-Location -PSProvider "FileSystem") (Split-Path $fileName -Leaf)
  548.    }
  549. }
  550.  
  551. function Get-UtcTime {
  552.    Param($Format="yyyyMMddhhmmss")
  553.    [DateTime]::Now.ToUniversalTime().ToString($Format)
  554. }
  555.  
  556. ## Get-CredentialBetter
  557. ## An improvement over the default cmdlet which has no options ...
  558. ###################################################################################################
  559. ## History
  560. ## v 1.2 Refactor ShellIds key out to a variable, and wrap lines a bit
  561. ## v 1.1 Add -Console switch and set registry values accordingly (ouch)
  562. ## v 1.0 Add Title, Message, Domain, and UserName options to the Get-Credential cmdlet
  563. ###################################################################################################
  564. function Get-CredentialBetter{
  565. PARAM([string]$UserName, [string]$Title, [string]$Message, [string]$Domain, [switch]$Console)
  566.    $ShellIdKey = "HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds"
  567.    ## Carefully EA=SilentlyContinue because by default it's MISSING, not $False
  568.    $cp = (Get-ItemProperty $ShellIdKey ConsolePrompting -ea "SilentlyContinue")
  569.    ## Compare to $True, because by default it's $null ...
  570.    $cp = $cp.ConsolePrompting -eq $True
  571.  
  572.    if($Console -and !$cp) {
  573.       Set-ItemProperty $ShellIdKey ConsolePrompting $True
  574.    } elseif(!$Console -and $Console.IsPresent -and $cp) {
  575.       Set-ItemProperty $ShellIdKey ConsolePrompting $False
  576.    }
  577.  
  578.    ## Now call the Host.UI method ... if they don't have one, we'll die, yay.
  579.    $Host.UI.PromptForCredential($Title,$Message,$UserName,$Domain,"Generic","Default")
  580.  
  581.    ## BoyScouts: Leave everything better than you found it (I'm tempted to leave it = True)
  582.    Set-ItemProperty $ShellIdKey ConsolePrompting $cp -ea "SilentlyContinue"
  583. }
  584.  
  585. Export-ModuleMember -Function * -Alias *
  586. # Export-ModuleMember Invoke-Http, Receive-Http, Set-HttpCredential, Set-HttpDefaultUrl
  587. # SIG # Begin signature block
  588. # MIILCQYJKoZIhvcNAQcCoIIK+jCCCvYCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
  589. # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
  590. # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUaAKbQvIL86hvpi4AVRDIFI7Z
  591. # cKagggbgMIIG3DCCBMSgAwIBAgIJALPpqDj9wp7xMA0GCSqGSIb3DQEBBQUAMIHj
  592. # MQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxEjAQBgNVBAcTCVJvY2hl
  593. # c3RlcjEhMB8GA1UEChMYaHR0cDovL0h1ZGRsZWRNYXNzZXMub3JnMSgwJgYDVQQL
  594. # Ex9TY3JpcHRpbmcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MTcwNQYDVQQDEy5odHRw
  595. # Oi8vSHVkZGxlZE1hc3Nlcy5vcmcgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MScwJQYJ
  596. # KoZIhvcNAQkBFhhKYXlrdWxASHVkZGxlZE1hc3Nlcy5vcmcwHhcNMDkwMzE1MTkx
  597. # OTE5WhcNMTAwMzE1MTkxOTE5WjCBqzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5l
  598. # dyBZb3JrMRIwEAYDVQQHEwlSb2NoZXN0ZXIxITAfBgNVBAoTGGh0dHA6Ly9IdWRk
  599. # bGVkTWFzc2VzLm9yZzESMBAGA1UECxMJU2NyaXB0aW5nMRUwEwYDVQQDEwxKb2Vs
  600. # IEJlbm5ldHQxJzAlBgkqhkiG9w0BCQEWGEpheWt1bEBIdWRkbGVkTWFzc2VzLm9y
  601. # ZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPfqxOG9TQN+qZjZ6KfM
  602. # +zBK0YpjeyPL/cFgiGBhiIdYWTBtkbZydFr3IiERKRsUJ0/SKFbhf0C3Bvd/neTJ
  603. # qiZjH4D6xkrfdLlWMmmSXXqjSt48jZp+zfCAIaF8K84e9//7lMicdVFE6VcgoATZ
  604. # /eMKQky4JvphJpzDHYPLxLJQrKd0pjDDwspjdX5RedWkzeZBG7VfBnebLWUzgnMX
  605. # IxRQKfFCMryQDP8weceOnJjfJEf2FYmdpsEg5EKKKbuHsQCMVTxfteKdPvh1oh05
  606. # 1GWyPsvEPh4auJUT8pAVvrdxq+/O9KW/UV01UxjRYM1vdklNw8g7mkJTrrHjSjl7
  607. # tuugCnJjt5kN6v/OaUtRRMR68O85bSTVGOxJGCHUKlyuuTx9tnfIgy4siFYX1Ve8
  608. # xwaAdN3haTon3UkWzncHOq3reCIVF0luwRZu7u+TnOAnz2BRlt+rcT0O73GN20Fx
  609. # gyN2f5VGBbw1KuS7T8XZ0TFCspUdgwAcmTGuEVJKGhVcGAvNlLx+KPc5dba4qEfs
  610. # VZ0MssC2rALC1z61qWuucb5psHYhuD2tw1SrztywuxihIirZD+1+yKE4LsjkM1zG
  611. # fQwDO/DQJwkdByjfB2I64p6mk36OlZAFxVfRBpXSCzdzbgKpuPsbtjkb5lGvKjE1
  612. # JFVls1SHLJ9q80jHz6yW7juBAgMBAAGjgcgwgcUwHQYDVR0OBBYEFO0wLZyg+qGH
  613. # Z4WO8ucEGNIdU1T9MB8GA1UdIwQYMBaAFN2N42ZweJLF1mz0j70TMxePMcUHMAkG
  614. # A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgTwMCoGA1UdJQEB/wQgMB4GCCsGAQUF
  615. # BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMwCwYDVR0PBAQDAgTwMCwGCWCGSAGG+EIB
  616. # DQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQUF
  617. # AAOCAgEAmKihxd6KYamLG0YLvs/unUTVJ+NW3jZP16R28PpmidY/kaBFOPhYyMl2
  618. # bBGQABe7LA5rpHFAs0F56gYETNoFk0qREVvaoz9u18VfLb0Uwqtnq0P68L4c7p2q
  619. # V3nKmWjeI6H7BAyFuogxmMH5TGDfiqrrVSuh1LtPbkV2Wtto0SAxP0Ndyts2J8Ha
  620. # vu/2rt0Ic5AkyD+RblFPtzkCC/MLVwSNAiDSKGRPRrLaiGxntEzR59GRyf2vwhGg
  621. # oAXUqcJ/CVeHCP6qdSTM39Ut3RmMZHXz5qY8bvLgNYL6MtcJAx+EeUhW497alzm1
  622. # jInXdbikIh0d/peTSDyLbjS8CPFFtS6Z56TDGMf+ouTpEA16otcWIPA8Zfjq+7n7
  623. # iBHjeuy7ONoJ2VDNgqn9B+ft8UWRwnJbyB85T83OAGf4vyhCPz3Kg8kWxY30Bhnp
  624. # Fayc6zQKCpn5o5T0/a0BBHwAyMfr7Lhav+61GpzzG1KfAw58N2GV8KCPKNEd3Zdz
  625. # y07aJadroVkW5R+35mSafKRJp5pz20GDRwZQllqGH1Y/UJFEiI0Bme9ecbl2vzNp
  626. # JjHyl/jLVzNVrBI5Zwb0lCLsykApgNY0yrwEqaiqwcxq5nkXFDhDPQvbdulihSo0
  627. # u33fJreCm2fFyGbTuvR61goSksAvLQhvijLAzcKqWKG+laOtYpAxggOTMIIDjwIB
  628. # ATCB8TCB4zELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMRIwEAYDVQQH
  629. # EwlSb2NoZXN0ZXIxITAfBgNVBAoTGGh0dHA6Ly9IdWRkbGVkTWFzc2VzLm9yZzEo
  630. # MCYGA1UECxMfU2NyaXB0aW5nIENlcnRpZmljYXRlIEF1dGhvcml0eTE3MDUGA1UE
  631. # AxMuaHR0cDovL0h1ZGRsZWRNYXNzZXMub3JnIENlcnRpZmljYXRlIEF1dGhvcml0
  632. # eTEnMCUGCSqGSIb3DQEJARYYSmF5a3VsQEh1ZGRsZWRNYXNzZXMub3JnAgkAs+mo
  633. # OP3CnvEwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJ
  634. # KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB
  635. # gjcCARUwIwYJKoZIhvcNAQkEMRYEFIkZIwG8zpBkI/XtpIHDMXpbi0kcMA0GCSqG
  636. # SIb3DQEBAQUABIICAMZvVmo7gkXm4VzZsE0mPzEWV27Z5f116glbefnNS/23HK+t
  637. # S5am6TjriqlJ+ge5c6WcjcwSdsljoZGkkr2iSj7m03Xir0Y57/v6JWYAk1uX+0ec
  638. # wv8L4ww0bTGK5xbTkkmcH11JEh6aXlDmMIh0e7fj/pjjU+rxNiajxsZ6iVqp0i2J
  639. # tbjU+dj8wcyolt8qhQBLRGreZ8O3z8+UYPvTrcg5mTOtlZlhpgjPuVmlvZDOaNSx
  640. # zBv8oBZWHplknQfz6ZoSG79wilRWT1Yh7k/jSK8jFrEuziSZ3F1fgWAbOrho+0LK
  641. # 6dB6u2P38Ybx2P2b8zStVP4dBU8q3zEiRHTMqPUCcsAgCj0Xxzw4Ai3MJn3qYTzU
  642. # xsK66xmhWEPh3x94Tzoa6YHY6Su22JdfGYbBzZKY4iHHA16UJ1S3DUXbjK98wGmM
  643. # /QWZFkgme0A6Q9Ish7tkj3Xykr+JFMmLF87EIZuiQK8TseOr+N8hpDsIKe2dv/9M
  644. # YSyGP5kb4WipBLUhyA6j8j/LWAZIUDYeQTrVCwWv2uFdFCLY2MvdMWx0CXE7FSLg
  645. # H/ZC8Vr2fWjpYW7qQCbAnsj06NfhWQtnGwyItcOAlI31hDWYykfhgk3PYEybdEX3
  646. # Xg1a9rQt6r/P3h6fx7U3kP3hnbSfLLpE9FEnWlX61ovKC3tqxqqAGW2C3AaC
  647. # SIG # End signature block

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me