Sharepoint Online 2013 CSOM constructor error for AttachmentCollection object? - sharepoint

I'm writing a script to copy items from one list to another on a sharepoint online server. I'm using the 2013 sharepoint Client Side Object Model (CSOM) to script this in powershell ISE. This should be an easy task, but it's proving just the opposite. So far I can retreive all the items using camlquery and I'm just trying to duplicate those items and their attachments to another list. The error I receive is from trying to establish an attachmentCollection to retrieve all of the attachments from any item, here is a portion of the script that represents the problem:
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
$siteURL = "https://mysite.sharepoint.com"
$password = Read-Host -Prompt "Enter Password" -AsSecureString
$ctx = New-Object Microsoft.Sharepoint.Client.ClientContext($siteURL)
$credentials = New-Object Microsoft.Sharepoint.Client.SharepointOnlineCredentials("admin#mysite.sharepoint.com", $password)
$ctx.Credentials = $credentials
#...Bunch of code that establishes/loads web/lists/items, all works fine
function CopyItem $itemToCopy
function CopyItem ($oldItem)
{
Write-Host "Copying item" $oldItem.ID
$newItemCI = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
$newItem = $archList.AddItem($newItemCI)
$ctx.load($newItem)
#Update fields
$ctx.load($sourceList.Fields)
$ctx.ExecuteQuery()
foreach($field in $sourceList.Fields)
{
$newItem[$field.InternalName] = $oldItem[$field.InternalName]
}
$attachments = New-Object Microsoft.SharePoint.Client.AttachmentCollection #ERROR HERE
$attachments = $oldItem.AttachmentFiles
$ctx.load($attachments)
$newItem.AttachmentFiles.Add($attachments)
$newItem.Update()
$ctx.load($newItem)
$ctx.ExecuteQuery()
}
The error message says: "The List Archive Failed at: with this error message: Constructor not found. Cannot find an appropriate constructor for type Microsoft.SharePoint.Client.AttachmentCollection."
I get the same error if I try to create new-object as Attachment as well, can't find constructor. This is odd, as the constructor should be in the client.dll, but no luck. I've even tried repairing my 2013 CSOM files, no errors were found there. Any help on this is appreciated, thank you.

After a hellish amount of trial and error, I discovered that you did not need to declare a new-object when dealing with the attachmentCollection objects. You can simply set a variable up like so:
$attachments = $item.AttachmentFiles
$attachments is now an array of attachment objects.
However, there is still a huge issue of copying/adding attachments to new items, since sharepoint has a horrible system for managing these attachments and does not initially have a folder to store them, nor can you create a folder directly. I'm still having trouble copying attachments between items, if anyone has knowledge of how to accomplish this, I would love help on that as well.
The main problem in adding attachments to AttachmentFiles property is that it uses the $item.AttachmentFiles.Add() method, which requires the parameter to be a AttachmentCreationInformation Object, not an attachment Object. I have no idea how to make this function as I intend so that I can add a pre-existing attachment to a new item.

Related

Set folder title using SharePoint PnP in Powershell

I need to set the Title property of SharePoint folders under "My documents" library. I can use SharePoint PnP to create the folder, for example:
$folder = Resolve-PnPFolder -SiteRelativePath "My documents/folderA"
But I couldn't find a way to set the Title property of the folder using SharePoint PnP.
If you're using the default folders from sharepoint i don't think you can use the title property. You would need to create a new content type based on the default folder content type and then set the title property to optional or required. Just keep in mind that whenever you change the name property of the folder it will override the value of the title property.
If you mean rename the folder you can use this line of code to change the name property.
Rename-PnPFolder -Folder "My Documents/folderA" -TargetFolderName "folderB"
Try to modify the script as below to set a folder Title property:
#Config Variables
$SiteURL = "https://Tenant.sharepoint.com/sites/sitename"
$ListName="Documents"
$FolderServerRelativeURL = "/sites/sitename/Shared Documents/Folder1"
$UserAccount = "jerry#Tenant.onmicrosoft.com"
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)
#Get the Folder from URL
$Folder = Get-PnPFolder -Url $FolderServerRelativeURL
#Set Permission to Folder
Set-PnPListItem -List $ListName -Identity $Folder.ListItemAllFields -Values #{"Title" = "Test Title"}

How to load > 1 million items to a SharePoint Online List

Can anyone suggest a reasonably practical and efficient way to load 1.2 million test items into a SharePoint Online list?
Background: We've decided to build a new application on top of SharePoint Online. Other application architecture options have all proved non-viable for various reasons. The application will use several SharePoint lists for persistence, one of which will be large, about 1.2 million items at peak. (Yes, we're planning ways to handle the 5000 item view limit.) To test viability of the architecture (including those view limit tactics) we need to create 1.2M test items in a list. Nothing we've tried has been practical:
Tried making POST calls to the REST API, with 5 concurrent threads so it will finish in a reasonable time. This fails after a bit with a HTTP 429 "Too many requests".
Tried uploading a spreadsheet with 1.2M rows. This fails at 130K entries each time, and I don't see a practical way to either upload / append to an existing list, nor to append items from one list to another existing list.
Tried running a Workflow (SharePoint 2013 variety, if that matters). This works but runs way too slow single threaded and I'm hesitant to try multiple concurrent workflows because this is a shared environment and if I trash the server that would be way not good.
Thanks in advance for any pointers!
You could try to use pnp powershell to add more than 1 million items.
$username = "amos#contoso.onmicrosoft.com"
$password = "password"
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force)
Connect-PnPOnline -Url https://contoso.sharepoint.com/sites/dev -Credentials $cred
$ListName ="testn"
for($i=0;$i -lt 1000001;$i++){
Add-PnPListItem -List $ListName -Values #{"Title" = "test";}
}
Fastest way to load and process items from SPO using PnPPowershell goes something like following. Idea is to not initialize the items collection in any variable and directly process the items by page size.
Get-PnpListItem -List "{ListName}" -Fields "Field1","Field2","Fieldn" -PageSize 5000 | % {$i=0}{
% {$i=0}{
Do not move { to next line, I know it's weird but if you move, then good luck.
$item = $_
#Do your stuff with $item
Write-Host $item.Id
}

excel creation with powershell

I try to create a excel file in a powershell script using this code :
$xl = New-Object -ComObject "Excel.Application"
$xl.Visible = $false
$xl.DisplayAlerts = $false
$wb = $xl.Workbooks.Open($scriptPath + "\..\..\NeededTools\ExploitationApplication.xlsm")
$global:ws = $wb.sheets.Item(3)
And I face this exception :
New-Object : Retrieving the COM class factory for component with CLSID
{00000000-0000-0000-0000-000000000000} failed due to the following
error: 80040154 Class not registered (Exception from HRESULT:
0x80040154 (REGDB_E_CLASSNOTREG)).
Do someone have informations about this exception or a sample used to generate a excel file correctly ?
Is it possible to have this error because I dont have excel on this server ?
You do not have Excel installed. Or you have, and need to run repair.
I had the same problem in my Desktop from a C# application after a Windows/Office update from my company IT (Office16). It worked for 5 years without any problems.
I create a Powershell script that launch excel to update a table that works well in my Laptop but still not in my Desktop.
After long search and follow the indication from this link (https://social.technet.microsoft.com/Forums/lync/en-US/05a1635d-142c-4866-8455-1341280967fd/windows-explorer-preview-of-office-2016-files-does-not-work?forum=Office2016setupdeploy).
I found that some information was missing in the Windows registry.
In details: comparing the Registry key "Computer\HKEY_CLASSES_ROOT\WOW6432Node\CLSID{00024500-0000-0000-C000-000000000046}" from my Laptop, in my Desktop I had only one key, "InprocServer32" instead of 5 keys.
I added the following key folders and values under "Computer\HKEY_CLASSES_ROOT\WOW6432Node\CLSID{00024500-0000-0000-C000-000000000046}":
"LocalServer32" => default: "C:\Program Files (x86)\Microsoft Office\Root\Office16\EXCEL.EXE /automation"
"ProgID" => default: "Excel.Application.16"
"VersionIndependentProgID" => default: "Excel.Application"
"InprocHandler32" => default: "ole32.dll"
Note: the "LocalServer32" was enough to run the script
Registry key structure
You do not have Excel installed. Or you have, and have to repair it.

try to modify a item filed in sharepoint using powershell

this is some code I wrote:
Add-PSSnapin Microsoft.SharePoint.PowerShell
$webURL = "http://nycs00058260/sites/usitp"
$lists = "OsEM1","OsEM2","OsEM3","OsEM4"
$web = Get-SPWeb -Identity "http://nycs00058260/sites/usitp"
foreach($list in $lists)
... ...
Write-Host $item["Title"]
#$item["Item"]=$item["Title"] +" ,"+$webURL+"\"+$filename
$item["Item"]="$tmpValue"+" ,$item[Title]"
$item.Update()
}
}
}
it said: Unable to index into an object of type MicroSoft.SharePoint.SPListItem.
something worong when I change the $item["Item"] value?
There are a few reasons that cause this behavior:
Your permissions don't match what you need to change an item. If you have PowerShell rights, this is often not the case.
Your list is somehow corrupted. This could have something to do with site columns, content types, the list itself, or views. If you created and did not update the list schema (definition), it wouldn't let you edit it.
You don't have AllowUnsafeUpdates set to on for the SPWeb (site) object.
All three of these issues generally have better (matching) error messages but sometimes SharePoint doesn't give you all the information that you need in the error messages.
If you need more details, please ask.

Retrieve Details of Deployed Solutions in SharePoint using PowerShell

I need to retrieve the details of all deployed SharePoint solutions, as are displayed in the Central Administration > Operations > Solution Management (AKA the Solution Store), using a PowerShell script (v2.0). Can anyone offer any guidance on how to retrieve this information from the SharePoint solution store via the SharePoint API?
Thanks, MagicAndi.
This is actually pretty easy to do. You conect to the SP Farm and just request get_Solutions.
Here is an example:
# Connect to the Farm
$SPfarm = [Microsoft.SharePoint.Administration.SPFarm]::get_Local()
# What Solution are we looking for?
$solution = "sharepointlearningkit.wsp";
# Get the solutions
$currentSolution = $SPfarm.get_Solutions() | Where-Object { $_.DisplayName -eq $solution; }
$currentSolution;
Based on Mitchell's answer, I have used:
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
function Get-LocalSPFarm()
{
return [Microsoft.SharePoint.Administration.SPFarm]::Local
}
function List-Solutions()
{
$farm = Get-LocalSPFarm
foreach ($solution in $farm.Solutions)
{
Write-Host($solution.DisplayName)
# Get-Member -InputObject $solution -MemberType property
}
}
All credit to Mitchell!
You can call stsadm.exe -o enumsolutions from your powershell script. It returns XML data which you can easily convert to [xml] data type and see whatever you need from that.
(stsadm lives in c:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin)
The output consists of statements similar to this
<Solution Name="yoursolution.wsp">
<Id>ab693dcd-6483-45ad-abba-9c996c67b6e0</Id>
<File>yoursolution.wsp</File>
<Deployed>TRUE</Deployed>
<WebApplicationSpecific>TRUE</WebApplicationSpecific>
<ContainsGlobalAssembly>TRUE</ContainsGlobalAssembly>
<ContainsCodeAccessSecurityPolicy>FALSE</ContainsCodeAccessSecurityPolicy>
<Deployment WebApplication="http://devserver/" />
<LastOperationResult>DeploymentSucceeded</LastOperationResult>
<LastOperationTime>10/26/2009 9:06 AM</LastOperationTime>
</Solution>
Here are three powershell cmdlets I use to pull back the solution information. Mine are simple compared to the ones above but I thought I would submit them anyway :)
In SP2010 Management Shell
To list all the solutions. Returns solution name, id and deployed status
Get-spsolutions
To list all the properties of a particular solution
get-spsolution -identity | select *
List all solutions, properties and output to a file to read :)
get-spsolution | select * | out-file c:\solutions.txt

Resources