{"id":436,"date":"2022-10-28T20:22:28","date_gmt":"2022-10-28T20:22:28","guid":{"rendered":"https:\/\/merserver.com\/?p=436"},"modified":"2022-10-28T20:22:28","modified_gmt":"2022-10-28T20:22:28","slug":"use-powershell-to-download-a-file-with-http-https-and-ftp","status":"publish","type":"post","link":"http:\/\/merserver.com\/index.php\/2022\/10\/28\/use-powershell-to-download-a-file-with-http-https-and-ftp\/","title":{"rendered":"Use PowerShell to download a file with HTTP, HTTPS, and FTP"},"content":{"rendered":"\n<p><strong>In PowerShell, you can download a file via HTTP, HTTPS, and FTP with the Invoke-WebRequest cmdlet<\/strong><br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Download with SMB\u00a0^<\/h2>\n\n\n\n<p>If you are working in a hybrid IT environment, you often need to download or upload files from or to the cloud in your PowerShell scripts. If you only use Windows servers that communicate through the Server Message Block (SMB) protocol, you can simply use the&nbsp;<em>Copy-Item<\/em>&nbsp;cmdlet to copy the file from a network share:<\/p>\n\n\n\n<p>Copy-Item -Source \\\\server\\share\\file -Destination C:\\path\\<\/p>\n\n\n\n<p>This assumes that you have a VPN solution in place so that your cloud network virtually belongs to your intranet. Things get a bit more complicated if we are leaving the intranet and have to download from an extranet or the Internet.<a><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Download in PowerShell 2\u00a0^<\/h2>\n\n\n\n<p>The next simple case is where you have to download a file from the web or from an FTP server. In PowerShell 2, you had to use the&nbsp;<em>New-Object<\/em>&nbsp;cmdlet for this purpose:<\/p>\n\n\n\n<p><strong>$WebClient<\/strong> = New-Object System.Net.WebClient<\/p>\n\n\n\n<p><strong>$WebClient<\/strong>.DownloadFile(&#8220;https:\/\/www.contoso.com\/file&#8221;,&#8221;C:\\path\\file&#8221;)<\/p>\n\n\n\n<p>As of PowerShell 3, we have the&nbsp;<em>Invoke-WebRequest<\/em>&nbsp;cmdlet, which is more convenient to work with. It is PowerShell\u2019s counterpart to GNU&nbsp;<em>wget<\/em>, a popular tool in the Linux world, which is probably the reason Microsoft decided to use its name as an alias for&nbsp;<em>Invoke-WebRequest<\/em>. This is perhaps an understatement;&nbsp;<em>Invoke-WebRequest&nbsp;<\/em>is more powerful than&nbsp;<em>wget<\/em>&nbsp;because it allows you to not only download files but also parse them. But this is a topic for another post.<br><a><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Download with Invoke-WebRequest\u00a0^<\/h2>\n\n\n\n<p>To simply download a file through HTTP, you can use this command:<\/p>\n\n\n\n<p>Invoke-WebRequest -Uri &#8220;http:\/\/www.contoso.com&#8221; -OutFile &#8220;C:\\path\\file&#8221;<\/p>\n\n\n\n<p>In the example, we just download the HTML page that the web server at\u00a0www.contoso.com\u00a0generates. Note that, if you only specify the folder without the file name, as you can do with\u00a0<em>Copy-Item<\/em>, PowerShell will error:<\/p>\n\n\n\n<p><em>Invoke-WebRequest : Could not find a part of the path<\/em><\/p>\n\n\n\n<p>The shorter version for the command line is:<\/p>\n\n\n\n<p>wget &#8220;http:\/\/www.contoso.com&#8221; -outfile &#8220;file&#8221;<\/p>\n\n\n\n<p>If you omit the local path to the folder,&nbsp;<em>Invoke-WebRequest<\/em>&nbsp;will just use your current folder. The&nbsp;<em>-Outfile<\/em>&nbsp;parameter is always required if you want to save the file. The reason is that, by default,&nbsp;<em>Invoke-WebRequest<\/em>&nbsp;sends the downloaded file to the pipeline.<\/p>\n\n\n\n<p>However, the pipeline will then not just contain the contents of the file. Instead, you will find an object with a variety of properties and methods that allow you to analyze text files. If you send a binary file through the pipeline, PowerShell will treat it as a text file and you won\u2019t be able to use the data in the file.<\/p>\n\n\n\n<p>To only read the contents of the text file, we need to read the&nbsp;<em>Content<\/em>&nbsp;property of the object in the pipeline:<\/p>\n\n\n\n<p>Invoke-WebRequest &#8220;http:\/\/www.contoso.com&#8221; | Select-Object -ExpandProperty Content | Out-File &#8220;file&#8221;<\/p>\n\n\n\n<p>This command does the same thing as the previous one. The&nbsp;<em>-ExpandProperty<\/em>&nbsp;parameter ensures that the header (in this case, \u201cContent\u201d) won\u2019t be stored in the file.<\/p>\n\n\n\n<p>If you want to have the file in the pipeline&nbsp;<em>and<\/em>&nbsp;store it locally, you have to use&nbsp;<em>-PassThru<\/em>&nbsp;parameter:<\/p>\n\n\n\n<p>Invoke-WebRequest &#8220;http:\/\/www.contoso.com&#8221; -OutFile &#8220;file&#8221; -PassThru | Select-Object -ExpandProperty Content<\/p>\n\n\n\n<p>This command stores the web page in a file and displays the HTML code.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/4sysops.com\/wp-content\/uploads\/2015\/05\/Download-and-display-file.png\"><img decoding=\"async\" src=\"https:\/\/merserver.com\/wp-content\/uploads\/2022\/10\/Download-and-display-file_thumb.png\" alt=\"Download and display file\" title=\"Download and display file\"\/><\/a><\/figure>\n\n\n\n<p><em>Download and display file<\/em><a><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Authenticating at a web server\u00a0^<\/h2>\n\n\n\n<p>If the web server requires authentication, you have to use the&nbsp;<em>-Credential<\/em>&nbsp;parameter:<\/p>\n\n\n\n<p>Invoke-WebRequest -Uri https:\/\/www.contoso.com\/ -OutFile C:&#8221;\\path\\file&#8221; -Credential &#8220;yourUserName&#8221;<\/p>\n\n\n\n<p>Note that, if you omit the&nbsp;<em>-Credential<\/em>&nbsp;parameter, PowerShell will not prompt you for a user name and password and will throw this error:<\/p>\n\n\n\n<p><em>Invoke-WebRequest : Authorization Required<\/em><\/p>\n\n\n\n<p>You have to at least pass the user name with the&nbsp;<em>-Credential<\/em>&nbsp;parameter. PowerShell will then ask for the password. If you want to avoid a dialog window in your script, you can store the credentials in a&nbsp;<em>PSCredential<\/em>&nbsp;object:<\/p>\n\n\n\n<p><strong>$Credentials<\/strong> = Get-Credential<\/p>\n\n\n\n<p>Invoke-WebRequest -Uri &#8220;https:\/\/www.contoso.com&#8221; -OutFile &#8220;C:\\path\\file&#8221; -Credential <strong>$Credentials<\/strong><\/p>\n\n\n\n<p>You can use the\u00a0<em>-UseDefaultCredentials\u00a0<\/em>parameter instead of the\u00a0<em>-Credential<\/em>\u00a0parameter if you want to use the credentials of the current user. To add a little extra security, you might want to\u00a0encrypt the password. Make sure to always use HTTPS instead of HTTP if you have to authenticate on a remote server. If the web server uses basic authentication, your password will be transmitted in clear text if you download via HTTP.<\/p>\n\n\n\n<p>Note that this method only works if the web server manages authentication. Nowadays, most websites use the features of a content management system (CMS) to authenticate users. Usually, you then have to fill out an HTML form. I will explain in one of my next posts how you can do this with&nbsp;<em>Invoke-WebRequest<\/em>.<\/p>\n\n\n\n<p>Downloading files through FTP works analogous to HTTP. You also shouldn\u2019t use this protocol if security matters. To download multiple files securely, you had better work with SFTP or SCP.&nbsp;<em>Invoke-WebRequest<\/em>&nbsp;doesn\u2019t support these protocols. However, third-party PowerShell modules exist that step into the breach.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In PowerShell, you can download a file via HTTP, HTTPS, and FTP with the Invoke-WebRequest cmdlet Download with SMB\u00a0^ If you are working in a hybrid IT environment, you often need to download or upload files from or to the cloud in your PowerShell scripts. If you only use Windows servers that communicate through the&#8230;<\/p>\n<p class=\"more-link-wrap\"><a href=\"http:\/\/merserver.com\/index.php\/2022\/10\/28\/use-powershell-to-download-a-file-with-http-https-and-ftp\/\" class=\"more-link\">Read More<span class=\"screen-reader-text\"> &ldquo;Use PowerShell to download a file with HTTP, HTTPS, and FTP&rdquo;<\/span> &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-436","post","type-post","status-publish","format-standard","hentry","category-it"],"_links":{"self":[{"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/posts\/436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/comments?post=436"}],"version-history":[{"count":1,"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/posts\/436\/revisions"}],"predecessor-version":[{"id":438,"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/posts\/436\/revisions\/438"}],"wp:attachment":[{"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/media?parent=436"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/categories?post=436"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/merserver.com\/index.php\/wp-json\/wp\/v2\/tags?post=436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}