PoshCode Logo PowerShell Code Repository

HttpRest 2.0 by Joel Bennett 17 months ago (modification of post by Joel Bennett view diff)
diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/2097"></script>download | new post

Upgraded more functions to PowerShell 2.0 [CmdletBinding()]
Upgraded to MindTouch Dream 2.1

VERY OLD documentation on this post on HuddledMasses and I’m finally starting to update this to be an example of best practices … I guess ;)

  1. #requires -version 2.0
  2. ## HttpRest module version 2.0
  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_2.1.0.zip (code name Indigo) from http`://sourceforge.net/projects/dekiwiki/files/
  10. ##
  11. ## Unpack it, and you can find these dlls in the "dist" folder.
  12. ## Make sure to put them in the folder with this script module.
  13. ## You also need the PSD1 file. It's in a comment block at the bottom.
  14. ##
  15. ## For documentation of Dream:  http`://wiki.developer.mindtouch.com/Dream
  16. ####################################################################################################
  17. ## Version History
  18. ## 1.0   2008-11-30  First Release
  19. ## 1.0.1 2009-01-05  Added Get-WebPageContent
  20. ## 1.0.2 2009-05-14  Bug fix for Invoke-Http credential issues
  21. ## 1.1.0 2009-05-14  First release of a PowerShell 2.0 (CTP3/Windows7) version....
  22. ## 1.1.1 2009-05-15  Added Get-WebPageText and Get-Webfile ... cleaned up options
  23. ## 1.2   2009-08-09  Added Hashtable parsing on Get-DreamMessage
  24. ##                   Fixed parsing on Get-DreamPlug so we don't get errors on PowerShell 2
  25. ##                   Added ParameterSet on Invoke-Http to pass in a plug directly (easier to debug)
  26. ## 1.3   2010-07-27  Added a few more aliases to make life easier
  27. ## 1.4   2010-07-28  Changed Get-WebPageContent and Get-WebPageText to support pipline input
  28. ##                   Started adding help ...
  29. ## 2.0   2010-08-20  Upgrade to Mindtouch Dream 2.1
  30. ##                   Further Improvements to function behavior and parameter binding.
  31. ####################################################################################################
  32. ## Usage:
  33. ##   function Get-Google {
  34. ##     Invoke-Http GET http`://www.google.com/search @{q=$args} |
  35. ##       Receive-Http Xml "//h3[@class='r']/a" | Select href, InnerText
  36. ##   }
  37. ##   #########################################################################
  38. ##   function Get-WebFile($url,$cred) {
  39. ##     Invoke-Http GET $url -auth $cred | Receive-Http File
  40. ##   }
  41. ##   #########################################################################
  42. ##   function Send-Paste {
  43. ##   PARAM($PastebinURI="http`://posh.jaykul.com/p/",[IO.FileInfo]$file)
  44. ##   PROCESS {
  45. ##     if($_){[IO.FileInfo]$file=$_}
  46. ##
  47. ##     if($file.Exists) {
  48. ##       $ofs="`n"
  49. ##       $result = Invoke-Http POST $PastebinURI @{
  50. ##         format="posh"           # PowerShell
  51. ##         expiry="d"              # (d)ay or (m)onth or (f)orever
  52. ##         poster=$([Security.Principal.WindowsIdentity]::GetCurrent().Name.Split("\")[-1])
  53. ##         code2="$((gc $file) -replace "http`://","http``://")" # To get past the spam filter.
  54. ##         paste="Send"
  55. ##       } -Type FORM_URLENCODED -Wait
  56. ##       $xml = $result.AsDocument().ToXml()
  57. ##       write-output $xml.SelectSingleNode("//*[@class='highlight']/*").href
  58. ##     } else { throw "File Not Found" }
  59. ##   }}
  60. ##
  61. ####################################################################################################
  62. Write-Debug "PSScriptRoot: '$PSScriptRoot'"
  63. # This Module depends on MindTouch.Dream
  64. $null = Add-Type -Path "$PSScriptRoot\mindtouch.dream.dll" -ErrorAction Stop
  65. # MindTouch.Dream requires: mindtouch.dream.dll, mindtouch.core.dll, SgmlReaderDll.dll, and log4net.dll)
  66. # This Module also depends on utility functions from System.Web
  67. $null = Add-Type -Assembly System.Web -ErrorAction Stop
  68.  
  69. ## Some utility functions are defined at the bottom
  70. [uri]$global:url = ""
  71. [System.Management.Automation.PSCredential]$global:HttpRestCredential = $null
  72.  
  73. Function Get-DreamMessage {
  74. PARAM($Content,$Type)
  75.    #Write-Verbose "Content: $(if($Content){$Content.GetType()}else{"null"}) $($Content.Length) and Type: $(if($Type){$Type.GetType()}else{"null"})"
  76.    if($Type -is [String]) {
  77.       Write-Verbose "Specific Content: $([MindTouch.Dream.MimeType]::$Type)"
  78.       $Type = [MindTouch.Dream.MimeType]::$Type
  79.    }
  80.    
  81.    if($Type -is [MindTouch.Dream.MimeType] -and $Content) {
  82.       Write-Verbose "Specific Content: $([MindTouch.Dream.MimeType]::$Type)"
  83.       return [MindTouch.Dream.DreamMessage]::Ok( $Type, $Content )
  84.    }
  85.    
  86.    if(!$Content) {
  87.       Write-Verbose "No Content"
  88.       return [MindTouch.Dream.DreamMessage]::Ok()
  89.    }
  90.    if($Content -is [System.Xml.XmlDocument]) {
  91.       Write-Verbose "Xml Content"
  92.       return [MindTouch.Dream.DreamMessage]::Ok( $Content )
  93.    }
  94.    if($Content -is [Hashtable]) {
  95.       $kvp = $Content.GetEnumerator() | %{ new-object "System.Collections.Generic.KeyValuePair[[String],[String]]" $_.Key, $_.Value }
  96.       Write-Verbose "Hashtable content: $($kvp | ft -auto | out-string -stream | %{ "   $_ ".TrimEnd()} )"
  97.       return [MindTouch.Dream.DreamMessage]::Ok( $kvp )
  98.    }  
  99.    if(Test-Path $Content -EA "SilentlyContinue") {
  100.       Write-Verbose "File Content"
  101.       return [MindTouch.Dream.DreamMessage]::FromFile((Convert-Path (Resolve-Path $Content)));
  102.    }
  103.  
  104.    Write-Verbose "Unspecified string content"
  105.    return [MindTouch.Dream.DreamMessage]::Ok( $([MindTouch.Dream.MimeType]::TEXT), $Content )
  106. }
  107.  
  108. Function Get-DreamPlug {
  109.    [CmdletBinding()]
  110.    PARAM ( $Url, [hashtable]$With, [hashtable]$Headers )
  111.    if($Url -is [array]) {
  112.       Write-Verbose "URL is an array of parts"
  113.       if($Url[0] -is [hashtable]) {
  114.          Write-Verbose "URL is an array of hashtable parts"
  115.          $plug = [MindTouch.Dream.Plug]::New($global:url)
  116.          foreach($param in $url.GetEnumerator()) {
  117.             if($param.Value) {
  118.                $plug = $plug.At($param.Key,"=$(Encode-Twice $param.Value)")
  119.             } else {
  120.                $plug = $plug.At($param.Key)
  121.             }
  122.          }
  123.       }
  124.       else
  125.       {
  126.          [URI]$uri = Join-Url $global:url $url
  127.          $plug = [MindTouch.Dream.Plug]::New($uri)
  128.       }
  129.    }
  130.    elseif($url -is [string])
  131.    {
  132.       Write-Verbose "String URL"
  133.       trap { continue }
  134.       [URI]$uri = $url
  135.       if(!$uri.IsAbsoluteUri) {
  136.          $uri = Join-Url $global:url $url
  137.          Write-Verbose "Relative URL, appending to $($global:url) to get: $uri"
  138.       }
  139.       $plug = [MindTouch.Dream.Plug]::New($uri)
  140.    }
  141.    else {
  142.       Write-Verbose "No URL, using default $($global:url)"
  143.       $plug = [MindTouch.Dream.Plug]::New($global:url)
  144.    }
  145.    if($with) {
  146.       foreach($w in $with.GetEnumerator()) {
  147.          if($w.Value) {
  148.             $plug = $plug.With($w.Key,$w.Value)
  149.          }
  150.       }
  151.       Write-Verbose "Added 'with' params: $plug"
  152.    }
  153.    if($headers) {
  154.       foreach($header in $Headers.GetEnumerator()) {
  155.          if($header.Value) {
  156.             $plug = $plug.WithHeader($header.Key,$header.Value)
  157.          }
  158.       }
  159.       Write-Verbose "Added 'with' params: $plug"
  160.    }
  161.    return $plug
  162. }
  163.  
  164. Function Receive-Http {
  165. [CmdletBinding(DefaultParameterSetName="Response")]
  166. PARAM(
  167.    [Parameter(Position=1, Mandatory=$false)]
  168.    [ValidateSet("Xml", "File", "Text","Bytes")]
  169.    [Alias("As")]
  170.    $Output = "Xml"
  171. ,
  172.    [Parameter(Position=2, Mandatory=$false)]
  173.    [AllowEmptyString()]
  174.    [string]$Path
  175. ,
  176.    [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Result")]
  177.    [Alias("IO")]
  178.    [MindTouch.Tasking.Result[MindTouch.Dream.DreamMessage]]
  179.    $InputObject
  180. ,
  181.    [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Response")]
  182.    [MindTouch.Dream.DreamMessage]
  183.    $Response
  184. )
  185. PROCESS {
  186.    if($PSCmdlet.ParameterSetName -eq "Result") {
  187.       $Response = $InputObject.Wait()
  188.    }
  189.    
  190.    if($Response) {
  191.       Write-Debug $($response | Out-String)
  192.       if(!$response.IsSuccessful) {
  193.          Write-Output $response
  194.          Write-Host "Hello" -fore Yellow
  195.          Write-Verbose $($response|gm|out-string)
  196.          Write-Host "Hello" -fore Yellow
  197.          Write-Error $($response | Out-String)
  198.          throw "ERROR: '$($response.Status)' Response Status."
  199.       } else {  
  200.          switch($Output) {
  201.             "File" {
  202.                ## Joel's magic filename guesser ...
  203.                if(!$Path) {
  204.                   [string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $response.Headers["Content-Disposition"] ).Groups[1].Value
  205.                   $Path = $fileName.trim("\/""'")
  206.                   if(!$Path){
  207.                      if($response.ResponseUri)  {
  208.                         $fileName = $response.ResponseUri.Segments[-1]
  209.                         $Path = $fileName.trim("\/")
  210.                         if(!([IO.FileInfo]$Path).Extension) {
  211.                            $Path = $Path + "." + $response.ContentType.Split(";")[0].Split("/")[1]
  212.                         }
  213.                      }
  214.                   }
  215.                }
  216.                if($Path) {
  217.                   $File = Get-FileName $Path
  218.                } else {
  219.                   $File = Get-FileName
  220.                }
  221.                $null = [MindTouch.IO.StreamUtil]::CopyToFile( $response.AsStream(), $File, $response.ContentLength )
  222.                Get-ChildItem $File
  223.             }
  224.             "XDoc" {
  225.                if($Path) {
  226.                   $response.AsDocument()[$Path]
  227.                } else {
  228.                   $response.AsDocument()#.ToXml()
  229.                }
  230.             }
  231.             "Xml" {
  232.                if($Path) {
  233.                   $response.AsDocument().ToXml().SelectNodes($Path)
  234.                } else {
  235.                   $response.AsDocument().ToXml()
  236.                }
  237.             }
  238.             "Text" {
  239.                if($Path) {
  240.                   $response.AsDocument()[$Path] | % { $_.AsInnerText }
  241.                } else {
  242.                   $response.AsText()
  243.                }
  244.             }
  245.             "Bytes" {
  246.                $response.AsBytes()
  247.             }
  248.          }
  249.       }
  250.    } else {
  251.       Write-Warning "No Response!"
  252.       if($InputObject) { Write-Output $InputObject }
  253.    }
  254. }
  255. }
  256.  
  257. Function Invoke-Http {
  258. #.Synopsis
  259. #  Invoke an HTTP verb on a URI
  260. #.Description
  261. #  This is the core http rest cmdlet, which does most of the work and allows fetching web pages, files, etc.
  262. [CmdletBinding(DefaultParameterSetName="ByPath")]
  263. PARAM(
  264.    ## http`://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
  265.    ## Nobody actually uses HEAD or OPTIONS, right?
  266.    ## And nobody's even heard of TRACE or CONNECT ;)
  267.    [Parameter(Position=0, Mandatory=$false)]
  268.    [ValidateSet("POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS")] ## There are other verbs, but we need a list to make sure you don't screw up
  269.    [string]$Verb = "GET"
  270. ,
  271.    [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$false, ParameterSetName="WithPlug")]
  272.    [MindTouch.Dream.Plug]
  273.    $Plug
  274. ,
  275.    [Parameter(Position=1, Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="ByPath")]
  276.    [string]
  277.    $Path
  278. ,
  279.    [Parameter(Position=2, Mandatory=$false, ParameterSetName="ByPath")]
  280.    [hashtable]$With
  281. ,
  282.    [Parameter(Position=3, Mandatory=$false, ParameterSetName="ByPath")]
  283.    [hashtable]$Headers
  284. ,
  285.    [Parameter(Mandatory=$false)]
  286.    $Content
  287. ,
  288.    [Parameter(Mandatory=$false)]
  289.    [System.Collections.Generic.IEnumerable[MindTouch.Web.DreamCookie]]$Cookies
  290. ,
  291.    [Parameter(Mandatory=$false)]
  292.    $Type # Of Content
  293. ,
  294.    [Parameter(Mandatory=$false)]
  295.    [switch]$authenticate
  296. ,
  297.    [Parameter(Mandatory=$false)]
  298.    $credentials
  299. ,
  300.    [Parameter(Mandatory=$false)]
  301.    [switch]$Persistent  ## Note this ALSO causes WaitForResponse
  302. ,
  303.    [switch]$waitForResponse
  304. )
  305. PROCESS {
  306.       if($PSCmdlet.ParameterSetName -eq "ByPath") {
  307.          $Plug = Get-DreamPlug $Path $With $Headers
  308.       }
  309.  
  310.       ## Special Handling for FORM_URLENCODED
  311.       if($Type -like "Form*" -and !$Content) {
  312.          $dream = [MindTouch.Dream.DreamMessage]::Ok( $Plug.Uri )
  313.          $Plug = [MindTouch.Dream.Plug]::New( $Plug.Uri.SchemeHostPortPath )
  314.          Write-Verbose "RECREATED Plug: $($Plug.Uri.SchemeHostPortPath)"
  315.       } else {
  316.          $dream = Get-DreamMessage $Content $Type
  317.          Write-Verbose "Created Dream with Content: $($dream.AsText() |out-String)"
  318.       }
  319.      
  320.       if(!$plug -or !$dream) {
  321.          throw "Can't come up with a request!"
  322.       }
  323.      
  324.       if($Persistent -and $global:HttpRestCookies) {
  325.          $dream.Cookies.AddRange( $global:HttpRestCookies )
  326.       }
  327.       if($Cookies) {
  328.          $dream.Cookies.AddRange( $Cookies )
  329.       }
  330.      
  331.       if($authenticate -or $credentials){
  332.          if($credentials -is [System.Management.Automation.PSCredential]) {
  333.             Write-Verbose "AUTHENTICATING AS $($credentials.GetNetworkCredential().UserName)"
  334.             $plug = $plug.WithCredentials($credentials.GetNetworkCredential())
  335.          } elseif($credentials -is [System.Net.ICredentials]) {
  336.             Write-Verbose "AUTHENTICATING AS $($credentials.GetNetworkCredential().UserName)"
  337.             $plug = $plug.WithCredentials($credentials.GetNetworkCredential())
  338.          } else {
  339.             if($credentials) {
  340.                Write-Error "Credential must be a PSCredential or a System.Net.ICredentials"
  341.             }
  342.             $null = Get-HttpCredential  # Make sure they have global credentials
  343.             Write-Verbose "AUTHENTICATING AS $($global:HttpRestCredential.UserName)"
  344.             $plug = $plug.WithCredentials($global:HttpRestCredential.GetNetworkCredential())
  345.          }
  346.       }
  347.      
  348.       Write-Verbose $plug.Uri
  349.      
  350.       ## DEBUG:
  351.       Write-Debug "URI: $($Plug.Uri)"
  352.       Write-Debug "Verb: $($Verb.ToUpper())"
  353.       Write-Debug $($dream | gm | Out-String)
  354.      
  355.       $result = $plug.InvokeAsync( $Verb.ToUpper(),  $dream )
  356.      
  357.       Write-Debug $($result | Out-String)
  358.       #  if($DebugPreference -eq "Continue") {
  359.       #     Write-Debug $($result.Wait() | Out-String)
  360.       #  }
  361.      
  362.       if($waitForResponse -or $Persistent) {
  363.          $result = $result.Wait()
  364.          $global:HttpRestCookies = $result.Cookies
  365.       }
  366.      
  367.       write-output $result
  368.    
  369.       trap [MindTouch.Dream.DreamResponseException] {
  370.          Write-Error @"
  371. TRAPPED DreamResponseException
  372.      
  373. $($_.Exception.Response | Out-String)
  374.  
  375. $($_.Exception.Response.Headers | Out-String)
  376. "@
  377.          break;
  378.       }
  379. }
  380. }
  381.  
  382. Function Get-WebPageContent {
  383. #.Synopsis
  384. #  A wrapper for http get | rcv xml
  385. [CmdletBinding()]
  386. param(
  387.    [Parameter(Position=0,Mandatory=$true, ValueFromPipeline=$true)]
  388.    [string]$url
  389. ,
  390.    [Parameter(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. PROCESS {
  403.    invoke-http get $url $with -Authenticate:$Authenticate -Persist:$Persist | receive-http xml $xpath | select -expand outerxml
  404. }
  405. }
  406.  
  407. Function Get-WebPageText {
  408. #.Synopsis
  409. #  A wrapper for http get | rcv text
  410. [CmdletBinding()]
  411. param(
  412.    [Parameter(Position=0,Mandatory=$true, ValueFromPipeline=$true)]
  413.    [string]$url
  414. ,
  415.    [Parameter(Mandatory=$false)]
  416.    [string]$xpath=""
  417. ,
  418.    [Parameter(Position=2,Mandatory=$false)]
  419.    [hashtable]$with=@{}
  420. ,
  421.    [Parameter(Mandatory=$false)]
  422.    [switch]$Persist
  423. ,
  424.    [Parameter(Mandatory=$false)]
  425.    [switch]$Authenticate
  426. )
  427. PROCESS {
  428.    invoke-http get $url $with -Authenticate:$Authenticate -Persist:$Persist | receive-http text $xpath
  429. }
  430. }
  431.  
  432. Function Get-WebFile {
  433. #.Synopsis
  434. #  Download a file from a URI to the local computer
  435. [CmdletBinding()]
  436. param(
  437.    [Parameter(Position=0,Mandatory=$true, ValueFromPipeline=$true)]
  438.    [string]$url
  439. ,
  440.    [Parameter(Mandatory=$false)]
  441.    [Alias("output")]
  442.    [string]$path=""
  443. ,
  444.    [Parameter(Position=2,Mandatory=$false)]
  445.    [hashtable]$with=@{}
  446. ,
  447.    [Parameter(Mandatory=$false)]
  448.    [switch]$Persist
  449. ,
  450.    [Parameter(Mandatory=$false)]
  451.    [switch]$Authenticate
  452. )
  453. PROCESS {
  454.    Invoke-Http GET $url $with -Authenticate:$Authenticate -Persist:$Persist | Receive-Http File $path
  455. }
  456. }
  457.  
  458. Function Set-HttpDefaultUrl {
  459. #.Synopsis
  460. #  Set the base URI for making lots of calls to a single webservice without re-entering the full URL each time
  461. PARAM ([uri]$baseUri=$(Read-Host "Please enter the base Uri for your RESTful web-service"))
  462.    $global:url = $baseUri
  463. }
  464.  
  465. Function Set-HttpCredential {
  466. #.Synopsis
  467. #  Set the default credentials for making lots of calls to a single webservice without re-entering credentials
  468. param($Credential=$(Get-CredentialBetter -Title   "Http Authentication Request - $($global:url.Host)" `
  469.                                          -Message "Your login for $($global:url.Host)" `
  470.                                          -Domain  $($global:url.Host)) )
  471.    if($Credential -is [System.Management.Automation.PSCredential]) {
  472.       $global:HttpRestCredential = $Credential
  473.    } elseif($Credential -is [System.Net.NetworkCredential]) {
  474.       $global:HttpRestCredential = new-object System.Management.Automation.PSCredential $Credential.UserName, $(ConvertTo-SecureString $credential.Password)
  475.    }
  476. }
  477.  
  478. Function Get-HttpCredential {
  479. #.Synopsis
  480. #  Retrieves the default credentials for making lots of calls to a single webservice without re-entering credentials
  481.    if(!$global:url) { Set-HttpDefaultUrl }
  482.    if(!$global:HttpRestCredential) { Set-HttpCredential }
  483.    if(!$Secure) {
  484.       return $global:HttpRestCredential.GetNetworkCredential();
  485.    } else {
  486.       return $global:HttpRestCredential
  487.    }
  488. }
  489.  
  490. Function ConvertTo-UrlDoubleEncode {
  491. #.Synopsis
  492. #  Encode URLs twice for use with mindtouch APIs
  493.    param([string]$text)
  494.    return [System.Web.HttpUtility]::UrlEncode( [System.Web.HttpUtility]::UrlEncode( $text ) )
  495. }
  496.  
  497. Function Join-Url {
  498. #.Synopsis
  499. #  Like Join-Path, but for URIs
  500. [CmdletBinding()]
  501. param(
  502. [Parameter()]
  503. [uri]$baseUri=$global:url
  504. ,
  505. [Parameter(ValueFromRemainingArguments=$true)]
  506. [string[]]$path
  507. )
  508.    $ofs="/";$BaseUrl = ""
  509.    if($BaseUri -and $baseUri.AbsoluteUri) {
  510.       $BaseUrl = "$($baseUri.AbsoluteUri.Trim('/'))/"
  511.    }
  512.    return [URI]"$BaseUrl$([string]::join("/",@($path)).TrimStart('/'))"
  513. }
  514.  
  515. Function ConvertTo-SecureString {
  516. #.Synopsis
  517. #   Helper function which converts a string to a 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. Function Get-FileName {
  529. #.Synopsis
  530. #  Helper function to get a VALID filesystem path
  531.    param($fileName=$([IO.Path]::GetRandomFileName()), $path)
  532.    $fileName = $fileName.trim("\/""'")
  533.    ## if the $Path has a file name, and it's folder exists:
  534.    if($Path -and !(Test-Path $Path -Type Container) -and (Test-Path (Split-Path $path) -Type Container)) {
  535.       $path
  536.    ## if the $Path is just a folder (and it exists)
  537.    } elseif($Path -and (Test-Path $path -Type Container)) {
  538.       $fileName = Split-Path $fileName -leaf
  539.       Join-Path $path $fileName
  540.    ## If there's no valid $Path, and the $FileName has a folder...
  541.    } elseif((Split-Path $fileName) -and (Test-Path (Split-Path $fileName))) {
  542.       $fileName
  543.    } else {
  544.       Join-Path (Get-Location -PSProvider "FileSystem") (Split-Path $fileName -Leaf)
  545.    }
  546. }
  547.  
  548. Function Get-UtcTime {
  549.    Param($Format="yyyyMMddhhmmss")
  550.    [DateTime]::Now.ToUniversalTime().ToString($Format)
  551. }
  552.  
  553. Function Get-CredentialBetter {
  554. ## .Synopsis
  555. ##    Gets a credential object based on a user name and password.
  556. ## .Description
  557. ##    The Get-Credential function creates a credential object for a specified username and password, with an optional domain. You can use the credential object in security operations.
  558. ##
  559. ##    The function accepts more parameters to customize the security prompt than the default Get-Credential cmdlet (including forcing the call through the console if you're in the native PowerShell.exe CMD console), but otherwise functions identically.
  560. ##
  561. ## .Parameter UserName
  562. ##    A default user name for the credential prompt, or a pre-existing credential (would skip all prompting)
  563. ## .Parameter Title
  564. ##    Allows you to override the default window title of the credential dialog/prompt
  565. ##
  566. ##    You should use this to allow users to differentiate one credential prompt from another.  In particular, if you're prompting for, say, Twitter credentials, you should put "Twitter" in the title somewhere. If you're prompting for domain credentials. Being specific not only helps users differentiate and know what credentials to provide, but also allows tools like KeePass to automatically determine it.
  567. ## .Parameter Message
  568. ##    Allows you to override the text displayed inside the credential dialog/prompt.
  569. ##    
  570. ##    You can use this for things like presenting an explanation of what you need the credentials for.
  571. ## .Parameter Domain
  572. ##    Specifies the default domain to use if the user doesn't provide one (by default, this is null)
  573. ## .Parameter GenericCredentials
  574. ##    The Get-Credential cmdlet forces you to always return DOMAIN credentials (so even if the user provides just a plain user name, it prepends "\" to the user name). This switch allows you to override that behavior and allow generic credentials without any domain name or the leading "\".
  575. ## .Parameter Inline
  576. ##    Forces the credential prompt to occur inline in the console/host using Read-Host -AsSecureString (not implemented properly in PowerShell ISE)
  577. ##
  578. [CmdletBinding(DefaultParameterSetName="Better")]
  579. PARAM(
  580.    [Parameter(Position=1,Mandatory=$false)]
  581.    [Alias("Credential")]
  582.    [PSObject]$UserName=$null,
  583.    [Parameter(Position=2,Mandatory=$false)]
  584.    [string]$Title=$null,
  585.    [Parameter(Position=3,Mandatory=$false)]
  586.    [string]$Message=$null,
  587.    [Parameter(Position=4,Mandatory=$false)]
  588.    [string]$Domain=$null,
  589.    [Parameter(Mandatory=$false)]
  590.    [switch]$GenericCredentials,
  591.    [Parameter(Mandatory=$false)]
  592.    [switch]$Inline
  593. )
  594. PROCESS {
  595.    if( $UserName -is [System.Management.Automation.PSCredential]) {
  596.       return $UserName
  597.    } elseif($UserName -ne $null) {
  598.       $UserName = $UserName.ToString()
  599.    }
  600.    
  601.    if($Inline) {
  602.       if($Title)    { Write-Host $Title }
  603.       if($Message)  { Write-Host $Message }
  604.       if($Domain) {
  605.          if($UserName -and $UserName -notmatch "[@\\]") {
  606.             $UserName = "${Domain}\${UserName}"
  607.          }
  608.       }
  609.       if(!$UserName) {
  610.          $UserName = Read-Host "User"
  611.          if(($Domain -OR !$GenericCredentials) -and $UserName -notmatch "[@\\]") {
  612.             $UserName = "${Domain}\${UserName}"
  613.          }
  614.       }
  615.       return New-Object System.Management.Automation.PSCredential $UserName,$(Read-Host "Password for user $UserName" -AsSecureString)
  616.    }
  617.    if($GenericCredentials) { $Credential = "Generic" } else { $Credential = "Domain" }
  618.    
  619.    ## Now call the Host.UI method ... if they don't have one, we'll die, yay.
  620.    ## BugBug? PowerShell.exe disregards the last parameter
  621.    $Host.UI.PromptForCredential($Title, $Message, $UserName, $Domain, $Credential,"Default")
  622. }
  623. }
  624.  
  625. New-Alias Encode-Twice ConvertTo-UrlDoubleEncode
  626.  
  627. new-alias gwpc Get-WebPageContent -EA "SilentlyContinue"
  628. new-alias gwpt Get-WebPageText    -EA "SilentlyContinue"
  629. new-alias http Invoke-Http        -EA "SilentlyContinue"
  630. new-alias rcv  Receive-Http       -EA "SilentlyContinue"
  631.  
  632. Export-ModuleMember -Function Invoke-Http, Receive-Http, Get-WebPageContent, Get-WebPageText, Get-WebFile, ConvertTo-UrlDoubleEncode, Get-HttpCredential, Set-HttpCredential, Set-HttpDefaultUrl -Alias *
  633.  
  634. ##########################################################################################
  635. ##### HttpRest.psd1
  636. ##########################################################################################
  637. ## #
  638. ## # Module manifest for module 'HttpRest'
  639. ## # Generated by: Joel Bennett
  640. ## # Generated on: 3/19/2009
  641. ## #
  642. ##
  643. ## @{
  644. ##
  645. ## # These modules will be processed when the module manifest is loaded.
  646. ## ModuleToProcess = 'HttpRest.psm1'
  647. ##
  648. ## # This GUID is used to uniquely identify this module.
  649. ## GUID = '49fc4e2a-0270-467d-a652-a9ba8f82e97b'
  650. ##
  651. ## # The author of this module.
  652. ## Author = 'Joel Bennett'
  653. ##
  654. ## # The company or vendor for this module.
  655. ## CompanyName = 'http://HuddledMasses.org'
  656. ##
  657. ## # The copyright statement for this module.
  658. ## Copyright = 'Copyright (c) 2008, Joel Bennett. Released under Ms-PL license.'
  659. ##
  660. ## # The version of this module.
  661. ## ModuleVersion = '2.0'
  662. ##
  663. ## # A description of this module.
  664. ## Description = 'This module provides functions for working Http services.  Everything from downloading web pages, posting forms, and parsing HTML as XML, to downloading images and files, to interacting with REST web APIs'
  665. ##
  666. ## # The minimum version of PowerShell needed to use this module.
  667. ## PowerShellVersion = '2.0'
  668. ##
  669. ## # The CLR version required to use this module.
  670. ## CLRVersion = '2.0'
  671. ##
  672. ## # Functions to export from this manifest.
  673. ## FunctionsToExport = '*'
  674. ##
  675. ## # Aliases to export from this manifest.
  676. ## AliasesToExport = '*'
  677. ##
  678. ## # Variables to export from this manifest.
  679. ## VariablesToExport = '*'
  680. ##
  681. ## # Cmdlets to export from this manifest.
  682. ## CmdletsToExport = '*'
  683. ##
  684. ## # This is a list of other modules that must be loaded before this module.
  685. ## RequiredModules = @()
  686. ##
  687. ## # The script files (.ps1) that are loaded before this module.
  688. ## ScriptsToProcess = @()
  689. ##
  690. ## # The type files (.ps1xml) loaded by this module.
  691. ## TypesToProcess = @()
  692. ##
  693. ## # The format files (.ps1xml) loaded by this module.
  694. ## FormatsToProcess = @()
  695. ##
  696. ## # A list of assemblies that must be loaded before this module can work.
  697. ## RequiredAssemblies = 'autofac.dll', 'log4net.dll', 'mindtouch.core.dll', 'SgmlReaderDll.dll', 'mindtouch.dream.dll'
  698. ##
  699. ## # Module specific private data can be passed via this member.
  700. ## PrivateData = ''
  701. ##
  702. ## }

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