Download file with SmartCard Authentication

Welcome Forums General PowerShell Q&A Download file with SmartCard Authentication

This topic contains 4 replies, has 2 voices, and was last updated by

3 years, 5 months ago.

  • Author
  • #31078

    Points: 0
    Rank: Member

    I need to download a PDF file from a SharePoint Server that requires SmartCard Authentication. This powershell file will need to be run multiple times a day and by different users. The only method of authentication is via SmartCard. How can I do this?

    I have tried the following method, where I first tried to retrieve credentials from:

    $object = new-object Microsoft.VisualBasic.Devices.Network
    Write-Host "Please Select SmartCard from dropdown and enter PIN.";
    $credential = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "NetBiosUserName")

    then did the following:

    1) $web.Credentials = $credential
    $web.DownloadFile($url, $path)

    2) $object.DownloadFile($url, $path, $credential.username, $credential.password , $true, 500, $true, 'DoNothing')

    Neither method worked.

    If I create an instance of internet explorer I can open the PDF file, but I cannot get it to download automatically. Ideally, besides opening the powershell file and clicking authenticate on the SmartCard popup, everything should be invisible to the user. If not invisible, then everything would close down.

  • #31112

    Points: 0
    Rank: Member

    Smart card authentication for a website can normally be treated like a website that requires a certificate. Windows will handle any operations that require the private key, and it will prompt you for your PIN when needed. If you can use Invoke-WebRequest, it has a -Certificate parameter and an -OutFile parameter for saving a file. Try this (it depends on $Url and $Path already being defined):

    Add-Type -AssemblyName System.Security
    # You can do more filtering here if there are other cert requirements...
    $ValidCerts = [System.Security.Cryptography.X509Certificates.X509Certificate2[]](dir Cert:\CurrentUser\My | where { $_.NotAfter -gt (Get-Date) })
    # You could check $ValidCerts, and not do this prompt if it only contains 1...
    $Cert = [System.Security.Cryptography.X509Certificates.X509Certificate2UI]::SelectFromCollection(
        'Choose a certificate',
        'Choose a certificate',
    ) | select -First 1
    $IwrParams = @{
        Uri = $Url       # Uri to file to download
        OutFile = $Path  # Path to where file should be downloaded (include filename)
        Certificate = $Cert
    Invoke-WebRequest @IwrParams

    There are some scenarios where that still won't work, though, so let me know what happens when you try it...

  • #31152

    Points: 0
    Rank: Member


    Thanks for the reply. Amateur hour here, sorry, I should have mentioned I am stuck with powershell v2. I was under the impression from earlier research that Invoke-webrequest is for version 3 and up; please correct me if I am wrong as I could not get it to work earlier. I have not had a chance to try your code. Any ideas for powershell v2?

  • #31157

    Points: 0
    Rank: Member


    You're right, Invoke-WebRequest isn't available in v2. I think it just uses the .NET WebRequest and WebResponse objects, though, which should be available. Try this (don't forget to fill in the first three variables):

    $Url = 'URL HERE'
    $OutFilePath = 'OUTPUT FILE NAME HERE'
    $Cert = 'USER CERT HERE'
    if (Test-Path $OutFilePath) {
        throw "'$OutFilePath' already exists!"
    # Create webrequest that contains the selected certificate, and try to get a response
    $Request = [System.Net.WebRequest]::Create($Url)
    try {
        $Response = $Request.GetResponse()
    catch {
        # You could present a nicer message here
        Write-Error $_
    if ($Response) {
        # You'll probably want to check out the $Response object before doing anything with
        # it (probably at least check $Response.StatusCode)
        # There's probably a shorter/cleaner/better way to do this, but this will create a buffer and a filestream,
        # then transfer the binary data from the $Response's stream to the filestream using the buffer...
        $Buffer = New-Object byte[] 1024  # You can adjust the buffer size
        $OutFileStream = [System.IO.File]::Create($OutFilePath)   # This will overwrite an existing file!
        $ResponseStream = $Response.GetResponseStream()
        while (($BytesRead = $ResponseStream.Read($Buffer, 0, $Buffer.Length))) {
            $OutFileStream.Write($Buffer, 0, $BytesRead)
        # Cleanup
  • #31305

    Points: 0
    Rank: Member


    You are a PowerShell Genius! Combining your two threads worked perfect.

The topic ‘Download file with SmartCard Authentication’ is closed to new replies.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort