3

I'm hoping somebody can shed light on this, because it has been driving me to distraction.

I have a script which will save the reports it creates to a sharepoint document library via UNC path, if the path exists, otherwise it saves to the UNC path of a network drive location as a fallback.

I've noticed that checking with test-path, saving (through an msexcel COM object) or trying to open the folder in windows explorer using invoke-item only work if I had already accessed the sharepoint site (via web browser or windows explorer) since the PC last logged on (I'm running Windows 7 Enterprise Service Pack 1 - 64-bit edition).

If I haven't yet been on to sharepoint manually since last logon, test-path returns false, and the other methods cause ItemNotFoundException e.g.

ii : Cannot find path '\\uk.sharepoint.mydomain.local\sites\mycompany\myteam\Shared Documents\Reports' because it does not exist.
At line:1 char:1
+ ii '\\uk.sharepoint.mydomain.local\sites\mycompany\myteam\Shared Document ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (\\uk.sharepoint...\Reports:String) [Invoke-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.InvokeItemCommand

Example areas of code:

$LANPath = "\\myserver\myshare\teamdirs\scriptdir"
$SharepointPath = "\\uk.sharepoint.mydomain.local\sites\mycompany\myteam\Shared Documents\Reoprts"
$ScriptPath = $LANPath + "\bin"
If (Test-Path $SharepointPath) {$BasePath = $SharepointPath;write-host "Using sharepoint to save reports"} else {$BasePath = "$LANPath\Reports";write-host "Using LAN to save reports - sharepoint not accessible"}

and

$_|select -expandproperty HTMLBody | Out-File $($BasePath + "\Eml_body.html")
    Write-Host "Reformating HTML"
    $html = New-Object -ComObject "HTMLFile";
    $source = Get-Content -Path ($BasePath + "\Eml_body.html") -Raw;

and when saving the excel spreadsheet from within my COM object:

$workbook._SaveAs($fileout,[Microsoft.Office.Interop.Excel.XlFileFormat]::xlOpenXMLWorkbook,$Missing,$Missing,$false,$false,[Microsoft.Office.Interop.Excel.XlSaveAsAccessMode]::xlNoChange,[Microsoft.Office.Interop.Excel.XlSaveConflictResolution]::xlLocalSessionChanges,$true,$Missing,$Missing)
Graham Gold
  • 2,435
  • 2
  • 25
  • 34
  • 1
    I have a feeling the WebClient service will be able to help you out. `$webclient = New-Object System.Net.WebClient` This is the service used by Windows Explorer to access SharePoint locations. For reference: https://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.110).aspx – Thriggle Apr 06 '16 at 19:30
  • @Thriggle Ah, of course, it's a webserver running WebDAV, not a fileserver. Walks like a duck, quacks like a duck....not a duck! I had a play with webclient but couldn't get it to authenticate when setting `UseDefaultCredentials` to true. Instead, I've gone with Invoke-WebRequest as that should be enough to get the site into the WebDAV cache and thereafter UNC paths should work. If you post up as an answer I'll mark as answer accordingly. Syntax I used was `Invoke-WebRequest -Uri "http://uk.sharepoint.mydomain.local/sites/mycompany/myteame/Shared Documents/Reports" -UseDefaultCredentials` – Graham Gold Apr 07 '16 at 12:21
  • Scratch that - `Invoke-WebRequest` works for accessing the site but because it isn't using the UNC path, it's not invoking WebDAV, so I need to revisit WebClient and suss out why `UseDefaultCredentials` results in an authentication error - some more googling and searching of SO awaits – Graham Gold Apr 07 '16 at 13:34
  • Based on this remark on the [WebClient.Credentials documentation](https://msdn.microsoft.com/en-us/library/system.net.webclient.credentials(v=vs.110).aspx), the DefaultCredentials may be those of the ASP.NET worker process, which wouldn't necessarily have access to the files: `If the WebClient class is being used in a middle tier application, such as an ASP.NET application, the DefaultCredentials belong to the account running the ASP page (the server-side credentials). Typically, you would set this property to the credentials of the client on whose behalf the request is made.` – Thriggle Apr 07 '16 at 14:16

2 Answers2

0

You should be able to use a System.Net.WebClient object to access SharePoint file locations.

$client = New-Object System.Net.WebClient

The documentation for the WebClient.Credentials property suggests that the default credentials in this case may be for the ASP.NET server-side process rather than the current user's credentials:

If the WebClient class is being used in a middle tier application, such as an ASP.NET application, the DefaultCredentials belong to the account running the ASP page (the server-side credentials). Typically, you would set this property to the credentials of the client on whose behalf the request is made.

You therefore may want to set the credentials manually. You can plug them in as plain text...

$client.Credentials = New-Object System.Net.NetworkCredential("username","pswd","domain")

...or you could prompt the current user for their credentials.

$client.Credentials = Get-Credential

Here's an example that grabs a file and writes its content to the screen:

$client = New-Object System.Net.WebClient
$client.Credentials = Get-Credential

$data = $client.OpenRead("http://yoursharepointurl.com/library/document.txt")
$reader = New-Object System.IO.StreamReader($data)
$results = $reader.ReadToEnd()
Write-Host $results
$data.Close()
$reader.Close()
Thriggle
  • 7,009
  • 2
  • 26
  • 37
  • The 401 errors weren't a credential issue - it was taking exception to me using a path to a folder instead of to a file. Changed to read a file in and that works, but again, on a machine where I've not accessed the sharepoint site via WebDAV(using windows explorer) - I get an error: `Exception calling "DownloadString" with "1" argument(s): "The network path was not found. " At line:1 char:1 + $webclient.DownloadString($uri); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : WebException` – Graham Gold Apr 07 '16 at 14:59
  • Code used was: `$webclient = New-Object System.Net.WebClient; $uri = "\\uk.sharepoint.mydomain.local\sites\mycompany\myteam\Shared Documents\Reports\TRIGGER.txt"; $webclient.DownloadString($uri); ` and that file just contains the string `Success!` - so I know very quickly if it worked or not – Graham Gold Apr 07 '16 at 15:01
  • That is pretty bizarre. Seems like it must be caching a mapping for that UNC path once it's accessed. Can you skip using the UNC path and use the web address with the WebClient service, or is UNC required for other reasons? – Thriggle Apr 07 '16 at 15:20
  • My script is creating working files on the UNC path, and then also finally, the msexcel comobject that creates the final excel report saves to there - even if I done it all on a local or network drive, I'd still want the final reports on sharepoint. `copy-item` will be bound by the same issues as `test-path` when it comes to sharepoint and UNC. I guess I could use webclient to upload each finished report to sharepoint - it just feels like a kludge for something that should be easy - if I had much hair left I'd be tearing it out! – Graham Gold Apr 07 '16 at 15:37
  • 1
    I opted to try to more closely emulate what windows explorer does. `explorer "\\uk.sharepoint.mydomain.local\sites\mycompany\myteam\Shared Documents\Reviews"` works a treat to open the sharepoint UNC path, and thereafter `test-path` etc work fine with the path. Since this is a script intended to be user run and not scheduled, that's perfect for me - though I'd still like to be able to do it without for any non-interactive scripts I write in future. – Graham Gold Apr 09 '16 at 18:14
  • @GrahamGold nice, glad to hear you found a working approach (and relatively kludge free)! – Thriggle Apr 09 '16 at 18:28
0

I know this is an old thread but for those searching, check out this link: https://www.myotherpcisacloud.com/post/Sometimes-I-Can-Access-the-WebDAV-Share-Sometimes-I-Cant!

Because SharePoint exposes its shares over WebDav, you need to ensure the WebClient service is running on the machine from which you are accessing the path. Browsing the path in explorer automatically fires up the service, while command-line methods do not.

If you change the startup type of WebClient to Automatic, it should resolve the issue.

McOz
  • 1
  • 3