├── LICENSE.md ├── PsUrl └── PsUrl.psm1 ├── Readme.md └── Tests.ps1 /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mykhailo Chalyi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PsUrl/PsUrl.psm1: -------------------------------------------------------------------------------- 1 | ## 2 | ## Inspired by curl, adds some commands to work with web. 3 | ## 4 | 5 | function Get-Url { 6 | [CmdletBinding()] 7 | Param( 8 | [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0)] 9 | [String]$Url, 10 | [String]$ToFile, 11 | [Management.Automation.PSCredential]$Credential 12 | ) 13 | Write-Verbose "Get-Url is considered obsolete. Please use Get-WebContent instead" 14 | 15 | $client = (New-Object Net.WebClient) 16 | if ($Credential){ 17 | $ntwCred = $Credential.GetNetworkCredential() 18 | $client.Credentials = $ntwCred 19 | $auth = "Basic " + [Convert]::ToBase64String([Text.Encoding]::Default.GetBytes($ntwCred.UserName + ":" + $ntwCred.Password)) 20 | $client.Headers.Add("Authorization", $auth) 21 | } 22 | 23 | if ($ToFile -ne ""){ 24 | $client.DownloadFile($Url, $ToFile) 25 | } else { 26 | $client.DownloadString($Url) 27 | } 28 | <# 29 | .Synopsis 30 | Downloads from url as a string. 31 | .Description 32 | .Parameter Url 33 | URL to download 34 | .Parameter ToFile 35 | Optional parameter to download stuff to the file. 36 | .Example 37 | Get-Url http://chaliy.name 38 | 39 | Description 40 | ----------- 41 | Downloads content of the http://chaliy.name 42 | 43 | #> 44 | } 45 | 46 | function Get-WebContent { 47 | [CmdletBinding()] 48 | Param( 49 | [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0)] 50 | [String]$Url, 51 | [Management.Automation.PSCredential]$Credential, 52 | $Encoding 53 | ) 54 | $client = (New-Object Net.WebClient) 55 | if ($Credential){ 56 | $ntwCred = $Credential.GetNetworkCredential() 57 | $client.Credentials = $ntwCred 58 | $auth = "Basic " + [Convert]::ToBase64String([Text.Encoding]::Default.GetBytes($ntwCred.UserName + ":" + $ntwCred.Password)) 59 | $client.Headers.Add("Authorization", $auth) 60 | } 61 | if ($Encoding){ 62 | if ($Encoding -is [string]){ 63 | $Encoding = [Text.Encoding]::GetEncoding($Encoding) 64 | } 65 | $client.Encoding = $Encoding 66 | } 67 | 68 | try { 69 | $client.DownloadString($Url) 70 | } catch [System.Net.WebException] { 71 | throw "Request failed: ""$($_.Exception.Message)""" 72 | } 73 | 74 | <# 75 | .Synopsis 76 | Downloads content from given url as a string. 77 | .Description 78 | .Parameter Url 79 | URL to download 80 | .Parameter Credential 81 | Optional parameter to specified basic authorization credentials 82 | .Parameter Encoding 83 | Optional parameter to specified encoding of the content(e.g. Utf-8) 84 | .Example 85 | Get-WebContent http://chaliy.name 86 | 87 | Description 88 | ----------- 89 | Downloads content of the http://chaliy.name 90 | 91 | .Example 92 | Get-WebContent http://chaliy.name -Encoding Utf-8 93 | 94 | Description 95 | ----------- 96 | Downloads content of the http://chaliy.name with UTF-8 encoding 97 | 98 | .Link 99 | Send-WebContent 100 | 101 | #> 102 | } 103 | 104 | function Write-Url { 105 | [CmdletBinding()] 106 | Param( 107 | [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0)] 108 | [String]$Url, 109 | [HashTable]$Data, 110 | [String]$Content, 111 | [TimeSpan]$Timeout = [TimeSpan]::FromMinutes(1), 112 | [Management.Automation.PSCredential]$Credential, 113 | [String]$ContentType 114 | ) 115 | Write-Verbose "Write-Url is considered obsolete. Please use Send-WebContent instead" 116 | if ($Content -ne ""){ 117 | Send-WebContent -Url:$Url -Content:$Content -Timeout:$Timeout -Credential:$Credential -ContentType:$ContentType 118 | } else { 119 | Send-WebContent -Url:$Url -Data:$Data -Timeout:$Timeout -Credential:$Credential -ContentType:$ContentType 120 | } 121 | <# 122 | .Synopsis 123 | POST values to URL 124 | .Description 125 | .Parameter Url 126 | URL to POST 127 | .Parameter Data 128 | Hashtable of the data to post. 129 | .Parameter Timeout 130 | Optional timeout value, by default timeout is 1 minute. 131 | .Parameter ContentType 132 | Adds Content-Type header to request 133 | .Example 134 | Write-Url http://chaliy.name -Data @{"Foo" = "Bar" } 135 | 136 | Description 137 | ----------- 138 | POST's to the http://chaliy.name as application/x-www-form-urlencoded 139 | 140 | #> 141 | } 142 | 143 | 144 | function Send-WebContent { 145 | [CmdletBinding()] 146 | Param( 147 | [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0)] 148 | [String]$Url, 149 | [Parameter(ParameterSetName='Data')] 150 | [HashTable]$Data, 151 | [Parameter(ParameterSetName='Content')] 152 | [String]$Content, 153 | [TimeSpan]$Timeout = [TimeSpan]::FromMinutes(1), 154 | [Management.Automation.PSCredential]$Credential, 155 | [String]$ContentType, 156 | [HashTable]$Headers 157 | ) 158 | 159 | 160 | try{ 161 | $req = [Net.WebRequest]::Create($Url) 162 | $req.Method = "POST" 163 | $req.Timeout = $Timeout.TotalMilliseconds 164 | if ($Credential){ 165 | $ntwCred = $Credential.GetNetworkCredential() 166 | $auth = "Basic " + [Convert]::ToBase64String([Text.Encoding]::Default.GetBytes($ntwCred.UserName + ":" + $ntwCred.Password)) 167 | $req.Headers.Add("Authorization", $auth) 168 | $req.Credentials = $ntwCred 169 | $req.PreAuthenticate = $true 170 | } 171 | 172 | if ($ContentType -ne ""){ 173 | $req.ContentType = $ContentType 174 | } 175 | 176 | if ($Headers -ne $Null){ 177 | foreach($headerName in $Headers.Keys){ 178 | $req.Headers.Add($headerName, $Headers[$headerName]) 179 | } 180 | } 181 | 182 | switch($PSCmdlet.ParameterSetName) { 183 | Content { 184 | $reqStream = $req.GetRequestStream() 185 | $reqBody = [Text.Encoding]::Default.GetBytes($Content) 186 | $reqStream.Write($reqBody, 0, $reqBody.Length) 187 | } 188 | Data { 189 | Add-Type -AssemblyName System.Web 190 | $formData = [Web.HttpUtility]::ParseQueryString("") 191 | foreach($key in $Data.Keys){ 192 | $formData.Add($key, $Data[$key]) 193 | } 194 | $reqBody = [Text.Encoding]::Default.GetBytes($formData.ToString()) 195 | 196 | $req.ContentType = "application/x-www-form-urlencoded" 197 | $reqStream = $req.GetRequestStream() 198 | $reqStream.Write($reqBody, 0, $reqBody.Length) 199 | } 200 | } 201 | 202 | $reqStream.Close() 203 | 204 | $Method = $req.Method 205 | Write-Verbose "Execute $Method request" 206 | foreach($header in $req.Headers.Keys){ 207 | Write-Verbose ("$header : " + $req.Headers[$header]) 208 | } 209 | 210 | $resp = $req.GetResponse() 211 | $respStream = $resp.GetResponseStream() 212 | $respReader = (New-Object IO.StreamReader($respStream)) 213 | $respReader.ReadToEnd() 214 | } 215 | catch [Net.WebException]{ 216 | if ($_.Exception -ne $null -and $_.Exception.Response -ne $null) { 217 | $errorResult = $_.Exception.Response.GetResponseStream() 218 | $errorText = (New-Object IO.StreamReader($errorResult)).ReadToEnd() 219 | Write-Error "The remote server response: $errorText" 220 | } 221 | throw $_ 222 | } 223 | 224 | <# 225 | .Synopsis 226 | POST values to URL 227 | .Description 228 | .Parameter Url 229 | URL to POST 230 | .Parameter Data 231 | Hashtable of the data to post. 232 | .Parameter Timeout 233 | Optional timeout value, by default timeout is 1 minute. 234 | .Parameter ContentType 235 | Adds Content-Type header to the request 236 | .Parameter Headers 237 | Adds arbitrary headers to the request 238 | .Example 239 | Send-WebContent http://chaliy.name -Data @{"Foo" = "Bar" } 240 | 241 | Description 242 | ----------- 243 | POST's to the http://chaliy.name as application/x-www-form-urlencoded 244 | 245 | .Link 246 | Get-WebContent 247 | #> 248 | } 249 | 250 | 251 | Export-ModuleMember Get-Url #Obsolete 252 | Export-ModuleMember Write-Url #Obsolete 253 | 254 | Set-Alias gwc Get-WebContent 255 | Set-Alias swc Send-WebContent 256 | Export-ModuleMember Get-WebContent 257 | Export-ModuleMember Send-WebContent 258 | Export-ModuleMember -Alias gwc 259 | Export-ModuleMember -Alias swc -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # PsUrl Utils 2 | 3 | Set of commands to download from and post to the web 4 | 5 | # Features 6 | 7 | 1. Download content from any URL as a string 8 | 3. POST url encoded form to any URL 9 | 3. POST arbitrary requests to any URL 10 | 11 | # Examples 12 | 13 | For example, to download stuff from http://example.com, execute 14 | 15 | get-webcontent http://example.com 16 | 17 | You can also use pipes 18 | 19 | get-webcontent http://example.com | set-content example.html 20 | 21 | Using pipes actually allows running scripts directly from the web 22 | 23 | get-webcontent https://gist.github.com/raw/909561/hello_world.ps1 | invoke-expression 24 | 25 | And of course, you can POST content 26 | 27 | send-webcontent "http://example.com" -Data @{"Foo" = "Bar"} 28 | 29 | 30 | # Installation 31 | 32 | If you have [PsGet](https://github.com/psget/psget) installed, you can execute: 33 | 34 | install-module PsUrl 35 | 36 | which should output something like this: 37 | 38 | "C:\Users\[User]\Documents\WindowsPowerShell\Modules" is added to the PSModulePath environment variable 39 | Module PsUrl was successfully installed. 40 | 41 | Alternatively, here are the manual steps: 42 | 43 | 1. Copy `PsUrl.psm1` to your modules folder (e.g. `$Env:PSModulePath\PsUrl\` ) 44 | 2. Execute `Import-Module PsUrl` (or add this command to your profile) 45 | 3. Enjoy! 46 | 47 | # License 48 | 49 | This project is licensed under the terms of the MIT license. 50 | -------------------------------------------------------------------------------- /Tests.ps1: -------------------------------------------------------------------------------- 1 | $here = (Split-Path -parent $MyInvocation.MyCommand.Definition) 2 | import-module -name ($here + "\PsUrl\PsUrl.psm1") -force 3 | 4 | write-host Should support downloading stuff 5 | get-webcontent "http://example.com" | out-null 6 | 7 | 8 | write-host Should support downloading encoded stuff 9 | get-webcontent "http://example.com" -Encoding ([Text.Encoding]::Utf8) | out-null 10 | 11 | write-host Should support downloading encoded stuff 2 12 | get-webcontent "http://example.com" -Encoding utf-8 | out-null 13 | 14 | write-host Should support 404 15 | get-webcontent "http://us.blizzard.com/en-us/404/" -ErrorAction:SilentlyContinue 16 | 17 | write-host Should support downloading to file 18 | get-url "http://example.com" -ToFile "$here\example.html" 19 | if (-not (test-path "$here\example.html")){ write-error "example.html was not downloaded" } 20 | remove-item "$here\example.html" 21 | 22 | write-host Should support posting stuff 23 | send-webcontent "http://example.com" -Data @{"Foo" = "Bar"} | out-null 24 | 25 | write-host Should support posting stuff with headers 26 | send-webcontent "http://example.com" -Data @{"Foo" = "Bar"} -Headers @{"Something" = "Funny"} | out-null 27 | --------------------------------------------------------------------------------