使用PowerShell无法认证并下载SharePoint服务器Word文档列表
Let's break down why you're hitting that 401 error and fix it step by step. First, I notice a few small issues in your script that might be contributing, plus some SharePoint-specific authentication quirks that Start-BitsTransfer struggles with.
First: Fix Script Typos & Inconsistencies
Looking at your code, there are a couple of variable name mismatches and case inconsistencies that could throw off execution (even if they aren't the direct cause of the 401):
- You define
$ssLDocNamebut then use$ssLocalDocNamelater – these should be the same variable name. - You have
$passWord(capital W) but then reference$password(lowercase w) when creating the PSCredential object. PowerShell is case-insensitive for variables, but consistency avoids confusion.
Here's the corrected snippet for those parts:
$ssLocalDocName = Split-path $item -Leaf $ssLocalDocPath = "D:\FF\" + $ssLocalDocName $userName = "DOMAIN\JohnDoe" # Make sure this uses the full domain\username format $password = Get-Content D:\Password.txt | ConvertTo-SecureString -AsPlainText -Force # Add these flags if your password file is plaintext $C = new-object -typename System.Management.Automation.PSCredential -argumentlist $userName, $password
Why Start-BitsTransfer is Failing with 401
SharePoint often uses NTLM or Kerberos authentication, and Start-BitsTransfer's -Credential parameter doesn't always play nicely with these protocols, especially if you're trying to reuse an existing authenticated session (like the one from Invoke-WebRequest). Here are a few solutions:
Option 1: Replace Start-BitsTransfer with Invoke-WebRequest
Since you're already using Invoke-WebRequest with -UseDefaultCredentials successfully to fetch links, reuse that authentication context to download the files directly. This avoids the need to pass credentials separately:
foreach ($item in $invokeData) { $filename = "http://docs" + $item $ssLocalDocName = Split-path $item -Leaf $ssLocalDocPath = "D:\FF\" + $ssLocalDocName # Use Invoke-WebRequest with the same authentication as your initial call Invoke-WebRequest -Uri $filename -OutFile $ssLocalDocPath -UseDefaultCredentials }
Option 2: Fix Credential Format for Start-BitsTransfer
If you need to stick with Start-BitsTransfer, ensure your credentials are formatted correctly:
- Use the full domain username format (
DOMAIN\Username) instead of just "John Doe" – SharePoint requires this for domain authentication. - If your
Password.txtcontains plaintext (not encrypted), add-AsPlainText -ForcetoConvertTo-SecureStringto properly convert it. - Try adding the
-TransferPolicy Basicparameter to Start-BitsTransfer, which can help with some authentication scenarios:
Start-BitsTransfer -Credential $C -Source $filename -Destination $ssLocalDocPath -TransferPolicy Basic
Option 3: Use SharePoint-Specific PowerShell Modules (Most Reliable)
For consistent SharePoint file operations, use the PnP PowerShell module – it's built specifically for SharePoint and handles authentication seamlessly. Here's how to adapt your script:
- First install the module (run PowerShell as admin):
Install-Module -Name PnP.PowerShell -Force - Then rewrite your script to use PnP cmdlets:
$siteUrl = "http://d/D/O%20S/S/O/S/" $downloadPath = "D:\FF\" $userName = "DOMAIN\JohnDoe" $password = Get-Content D:\Password.txt | ConvertTo-SecureString -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential($userName, $password) # Connect to SharePoint Connect-PnPOnline -Url $siteUrl -Credentials $cred # Get all files matching your path pattern and download them Get-PnPListItem -List "Documents" | Where-Object { $_["FileRef"] -match "/Dev/O/S/OS2017-1/S/" } | ForEach-Object { Get-PnPFile -Url $_["FileRef"] -Path $downloadPath -FileName $_["FileLeafRef"] -AsFile }
This method avoids manual link parsing and handles SharePoint's authentication nuances out of the box.
内容的提问来源于stack exchange,提问作者Mikhail R

