Create folder with powershell in sharepoint (webservices) - powershell

I need to create a folder in sharepoint if it does not already exist. My powershell script is not running on the sharepoint server so I think I have to use the sharepoint web services? I am currently uploading files to sharepoint with powershell using webclient as below - but I need to create the folder for the file first... if it does not already exist;
# Upload the file
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = $credentials
$webclient.UploadFile($destination + "/" + $File.Name, "PUT", $File.FullName)
Is this possible to do with webclient? If not, how can this be done using the sharepoint web services?

Since you mentioned SharePoint Web Services, Lists.UpdateListItems Method could be utilized for that purpose, for example:
Function Create-Folder([string]$WebUrl,[string]$ListUrl,[string]$ListName,[string]$FolderName)
{
$url = $WebUrl + "/_vti_bin/lists.asmx?WSDL"
$listsProxy = New-WebServiceProxy -Uri $url -UseDefaultCredential
$batch = [xml]"<Batch OnError='Continue' RootFolder='$WebUrl/$ListUrl'><Method ID='1' Cmd='New'><Field Name='ID'>New</Field><Field Name='FSObjType'>1</Field><Field Name='BaseName'>$FolderName</Field></Method></Batch>"
$result = $listsProxy.UpdateListItems($ListName, $batch)
}
Usages
Create Orders folder under Documents library:
Create-Folder -WebUrl "http://contoso.intranet.com" -ListUrl "Documents" -ListName "Documents" -FolderName "Orders"
Create 2014 folder in Requests list:
Create-Folder -WebUrl "http://contoso.intranet.com" -ListUrl "Lists/Requests" -ListName "Requests" -FolderName "2014"
Update
If folder already exists then SOAP service will throw the error:
The operation failed because an unexpected error occurred. (Result
Code: 0x8107090d)
but since OnError attribute is set to Continue for Batch Element, PowerShell will continue the execution.

Related

Trouble creating folder in SharePoint Online (PnP module)

I am trying to use PowerShell to create a new folder in a Teams document library, using the PnP Sharepoint Online module.
I can authenticate to the site in both PowerShell and in a browser. Then I run this code:
$cred = Get-Credential
$result = Add-PnPFolder -Folder "/sites/SalesDemo/Shared Documents/General/Acme Corp" -Name "testfolder" -Connection (Connect-PnPOnline -Url 'https://tenant.sharepoint.com' -Credentials $cred)
The result looks fine, showing the name, type, items/size, and last modified time, but when I view the site in SharePoint or in Teams, I do not see "testfolder". However, "testfolder" is returned when I run:
Get-PnPFolderItem -FolderSiteRelativeUrl "/sites/SalesDemo/Shared Documents/General/Acme Corp" -ItemType Folder -Connection (Connect-PnPOnline -Url 'https://tenant.sharepoint.com' -Credentials $cred)
Unfortunately, there are other folders in "Acme Corp" that are not returned.
Where is my "testfolder" being created?
Update:
As discussed, when using Connect-PnPOnline, the url parameter should be the same as the site url where the library hosted, if it's hosting in specific site collection, the url should be:
https://Tenant.sharepoint.com/sites/SalesDemo
The testfolder should be located at the relative url:
/sites/SalesDemo/Shared Documents/General/Acme Corp
"Acnm Corp" should be a subfolder within /Shared Documents/General folder, the test folder should be there:

Programmatically delete the contents of SharePoint 2013 recycle bin

Scenario:
Client would like a PowerShell script wrote to delete the 2nd stage recycle bin for a SharePoint 2013 Site Collection
Client's SharePoint requires a credential authorization on load.
Issue:
I have researched, however in regards to SharePoint 2013, I have yet to find a script example that involves using my credentials. However in the SharePoint Online examples for programmatically deleting a SP recycle bin they use credential authorization.
My attempts to splice these two scripts together have been met with no success.
Question: Would somone be able to assist me by taking a look at my code and letting me know where I am going wrong?
##Variables for Processing
$SiteUrl = "https://MySite/sites/site"
Try {
#Setup the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$Context.Credentials = $Credentials
#Get the recycle bin
$Site = $Context.Site
$RecycleBinItems = $Site.RecycleBin
$Context.Load($Site)
$Context.Load($RecycleBinItems)
$Context.ExecuteQuery()
Write-Host "Total Number of Items found Recycle Bin:" $RecycleBinItems.Count
#sharepoint online powershell empty recycle bin
$RecycleBinItems.DeleteAll()
$Context.ExecuteQuery()
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}

Cannot open sharepoint UNC path unless already opened through Windows Explorer

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)
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()
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.

Powershell Sharepoint snapin when not on the sharepoint server

I am new to both powershell and sharepoint, and I need to make script to automate the removal and uploading of attachments from outlook to sharepoint. I have easily completed the first part of extracting the attachment, however the uploading to sharepoint has become difficult do to my company's rules. As I understand to use sharepoint cmdlets you need to add the sharepoint snap-in but I am unable to do so because I dont have access to the sharepoint server. Is there anyway to the snapin without being on the server and if not can I upload it another way?
You can't add the SP snap in unless the server is a SP server. Instead, use a webservice/webclient approach to upload the file. Something like this should work depending on your SP version:
http://blog.sharepoint-voodoo.net/?p=205
Accepted answer link is broken.
This script uses PowerShell to upload a file to a document library in SharePoint using purely web service calls so it could be done remotely, also meaning it should work with O365 though I have not tried.
These variables are used throughout the script for source file, destination file and authentication. If your workstation is on the same domain as SharePoint, and your logged on user has permissions to the SharePoint site, you can omit $username, $password, and $domain
$LocalPath = "C:\filename.docx"
$spDocLibPath = "http://site.contoso.com/sites/spteam/Shared Documents/"
$username = "someone"
$password = "somepassword"
$domain = "contoso"
$UploadFullPath = $spDocLibPath + $(split-path -leaf $LocalPath)
$WebClient = new-object System.Net.WebClient
if($username -eq "" -or $password -eq "" -or $password -eq "")
{
# Use Local Logged on User Credentials
$WebClient.Credentials = [System.Net.CredentialCache]::DefaultCredentials
}
else
{
# Alternate Login for specifying credentials
$WebClient.Credentials = new-object System.Net.NetworkCredential($username, $password, $domain)
}
$WebClient.UploadFile($UploadFullPath, "PUT", $LocalPath)
https://web.archive.org/web/20160404174527/http://blog.sharepoint-voodoo.net/?p=205

Download URL content using PowerShell

I am working in a script, where I am able to browse the web content or the 'url' but I am not able to copy the web content in it & download as a file.
This is what I have made so far:
$url = "http://sp-fin/sites/arindam-sites/_layouts/xlviewer.aspx?listguid={05DA1D91-F934-4419-8AEF-B297DB81A31D}&itemid=4&DefaultItemOpen=1"
$ie=new-object -com internetexplorer.application
$ie.visible=$true
$ie.navigate($url)
while($ie.busy) {start-sleep 1}
How can I copy the content of $url and save it to local drive as a file?
Update:
I got these errors:
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (401) Unauthorized." At :line:6 char:47 + (New-Object system.net.webclient).DownloadFile( <<<< "$url/download-url-content", 'save.html' )
Missing ')' in method call. At :line:6 char:68 + (New-Object system.net.webclient).DownloadFile( "$url", 'save.html' <<<<
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (401) Unauthorized." At :line:6 char:47 + (New-Object system.net.webclient).DownloadFile( <<<< "$url", 'save.html' )
Ok, let me explain more, on what I am trying to do: I have a excel file in our share point site & this is the file I am trying to download locally(any format), which is a part of the script, so that for the later part of the script, I can compare this file with other data & get an output.
Now if I can somehow map "my documents" from the site & able to download the file, that will also work for me.
Update Jan 2014: With Powershell v3, released with Windows 8, you can do this:
(Invoke-webrequest -URI "http://www.kernel.org").Content
Original Post, valid for Powershell Version 2
This solution is very similar to the other answers from stej, Jay Bazusi and Marco Shaw.
It is a bit more general, by installing a new module into your module directory, psurl. The module psurl adds new commands in case you have to do a lot of html-fetching (and POSTing) with powershell.
(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex
See the homepage of the code-sharing website http://psget.net/.
This nice line of PowerShell script will dowload GetPsGet.ps1 and send
it to Invoke-Expression to install PsGet Module.
Then install PsUrl, a Powershell Module inspired by curl:
To install something (in our case PsUrl) from central directory just type:
install-module PsUrl
get-module -name psurl
Output:
ModuleType Name ExportedCommands
---------- ---- ----------------
Script psurl {Get-Url, Send-WebContent, Write-Url, Get-WebContent}
Command:
get-command -module psurl
Output:
CommandType Name Definition
----------- ---- ----------
Function Get-Url ...
Function Get-WebContent ...
Alias gwc Get-WebContent
Function Send-WebContent ...
Alias swc Send-WebContent
Function Write-Url ...
You need to do this only once.
Note that this error might occur:
Q: Error "File xxx cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details."
A: By default, PowerShell restricts execution of all scripts. This is all about security. To "fix" this run PowerShell as Administrator and call
Set-ExecutionPolicy RemoteSigned
From now on, in your new powershell sessions/scripts, do this:
import-module psurl
get-url "http://www.google.com"
To download and save to a file, do this:
get-url "http://www.google.com" | out-file -filepath "myfile.html"
As I understand it, you try to use IE because if automatically sends your credentials (or maybe you didn't know of any other option).
Why the above answers don't work is because you try to download file from SharePoint and you send an unauthenticated request. The response is 401.
This works:
PS>$wc=new-object system.net.webclient
PS>$wc.UseDefaultCredentials = $true
PS>$wc.downloadfile("your_url","your_file")
if the the current user of Posh has rights to download the file (is the same as the logged one in IE).
If not, try this:
PS>$wc=new-object system.net.webclient
PS>$wc.Credentials = Get-Credential
PS>$wc.downloadfile("your_url","your_file")
If you just want to download web content, use
(New-Object System.Net.WebClient).DownloadFile( 'download url content', 'save.html' )
I'm not aware of any way to save using that interface.
Does this render the page properly:
PS>$wc=new-object system.net.webclient
PS>$wc.downloadfile("your_url","your_file")
As already answered in https://stackoverflow.com/a/35202299/4636579, but with a mandatory Proxy and the credentials. Without proxy, it would be:
$url="http://aaa.bbb.ccc.ddd/rss.xml"
$WebClient = New-Object net.webclient
$path="C:\Users\hugo\xml\test.xml"
$WebClient.DownloadFile($url, $path)
$web = New-Object Net.WebClient
$web | Get-Member
$content=$web.DownloadString("http://www.bing.com")
If you're truly only concerned with the raw string content, the best route, as mentioned by a few others, is using the constructs within .NET to do this. However, I think in the previous answers a few opportunities are missed.
It's often best to use WebRequest over WebClient as it provides better control over the entire request cycle
Response buffering via System.IO.StreamReader, made possible by using WebRequest
Creating a testable, reusable tool. Which is the very nature and purpose of PowerShell
function Get-UrlContent {
<#
.SYNOPSIS
High performance url fetch
.DESCRIPTION
Given a url, will return raw content as string.
Uses:
System.Net.HttpRequest
System.IO.Stream
System.IO.StreamReader
.PARAMETER Url
Defines the url to download
.OUTPUTS
System.String
.EXAMPLE
PS C:\> Get-UrlContent "https://www.google.com"
"<!doctype html>..."
#>
[cmdletbinding()]
[OutputType([String])]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string] $Url)
Write-Debug "`n----- [Get-UrlContent]`n$url`n------`n`n"
$req = [System.Net.WebRequest]::CreateHttp($url)
try {
$resp = $req.GetResponse()
}
catch {
Write-Debug "`n------ [Get-UrlContent]`nDownload failed: $url`n------`n"
}
finally {
if ($resp) {
$st = $resp.GetResponseStream()
$rd = [System.IO.StreamReader]$st
$rd.ReadToEnd()
}
if ($rd) { $rd.Close() }
if ($st) { $st.Close() }
if ($resp) { $resp.Close() }
}
}