All,
I am trying to create a list using a custom list template that includes content for SharePoint Online using powershell and CSOM. The list template for now is already loaded into the site collection. If I go through the UI, I can create the list on a site using the template including content without issue. If I try to do it through powershell, the list gets created but without the columns and or contents.
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword)
$clientContext.Credentials = $credentials
if (!$clientContext.ServerObjectIsNull.Value)
{
Write-Host "Connected to SharePoint Online site: '$Url'" -ForegroundColor Green
}
$web = $clientContext.Web
$templates = $clientContext.Site.GetCustomListTemplates($web)
$clientContext.Load($templates)
$clientContext.ExecuteQuery()
$template = $templates | Where-Object{ $_.Name -eq "SomeTemplate" }
$lci = New-Object Microsoft.SharePoint.Client.ListCreationInformation
$lci.Title = "Some List"
$lci.TemplateFeatureId = $template.FeatureId
$lci.TemplateType = $template.ListTemplateTypeKind
$lci.DocumentTemplateType = $template.ListTemplateTypeKind
$lists = $clientContext.Web.Lists;
$clientContext.Load($lists);
$clientContext.ExecuteQuery();
$list = $lists.Add($lci)
$list.Update()
$clientContext.ExecuteQuery()
I can't figure out what is missing, any help would be much appreciated.
I think you have to associate Fields to Content Type (CT) and then add this CT to your List.
Try look at this:
http://www.sharepointfire.com/2016/01/create-new-content-type-sharepoint-online-powershell/
In previous step he created Columns(Fields) which he used in creation:
$columns = "BlogNumber", "BlogText", "BlogUser"
Hope it will help you.
Alex
I Think you have to add the list template before update. It works for me
...
$lci.Title = "Some List"
$lci.TemplateFeatureId = $template.FeatureId
$lci.TemplateType = $template.ListTemplateTypeKind
$lci.DocumentTemplateType = $template.ListTemplateTypeKind
$lci.ListTemplate = $template
...
Related
I am trying to set the description on a Document Library in SharePoint Online using the PnP-PowerShell Commands, but it seems to be very intermittent in working, so I wanted to check what the correct way to do it is?
I create a new library with:
New-PnPList -Template DocumentLibrary -Title "TempLibrary"
Then try to set the Description with:
$l = Get-PnPList -Identity TempLibrary
$l.Description = "My Description Here"
Now clearly that doesn't work since I need to send the changes back with CSOM I assume?
So then I tried the following:
$ctx = Get-PnPContext
$l = Get-PnPList -Identity TempLibrary
$l.Description = "My Description Here"
$ctx.ExecuteQuery()
But this still didn't seem to work.
Any thoughts anyone has on how to do this reliably would be greatly appreciated.
Many thanks,
D.
UPDATE
Eurgh... This seems to work, but is this right? Is it expected? Doesn't feel very PowerShell like...
New-PnPList -Title "Test5" -Template DocumentLibrary
$t = Get-PnPList -Identity Test5
$ctx.Load($t)
$ctx.ExecuteQuery()
$t.Description = "Test5 Description"
$t.Update()
$ctx.ExecuteQuery()
Without loading the list you will not be able to set the description or other properties so the code is correct.
$ctx.Load($t)
Why do you think this is not PS like? :) Curious...
Use the following script. Hope it helps.
Add - PSSnapin Microsoft.SharePoint.PowerShell
function CreateList($spWeb, $listName)
{
$spTemplate = $spWeb.ListTemplates["Document Library"]
$spListCollection = $spWeb.Lists
$spListCollection.Add($listName, $listName, $spTemplate)
}
Function SetDescription($spWeb, $listName)
{
$path = $spWeb.url.trim()
$spList = $spWeb.GetList("$path/Lists/$listName")
$spList.Description = "--Your Desired Description--"
$spList.Update()
}
$siteCollectionUrl = "--Your Site Collection Url--"
$listName = "--Your Desired List Name--"
$spWeb = Get - SPWeb - Identity $siteCollectionUrl
CreateList $spWeb $listName
SetDescription $spWeb $listName
I want use powershell and EWS (see https://msdn.microsoft.com/en-us/library/office/dd633710(v=exchg.80).aspx) to search for emails that contain a particular string in the subject line.
My problem is that the emails reside in a user-defined folder in the inbox, rather than in one of the folders listed in the WellKnownFolderName enumeration (see https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx)
The example code that I have found to search for emails all wants to search in one of these well-known folder names rather than in an arbitrary user-specified folder.
does anyone have some example code that i can use as a reference to figure out how to do this [or does EWS limit you to searching for emails using a well-known folder name only].
My code so far is thus:
$email = "myemail#someplace.com"
$username = "myusername"
$password = "*****"
$domain = "mydomain"
$USER_DEFINED_FOLDER_IN_MAILBOX = "myRandomFolder"
$EXCHANGE_WEB_SERVICE_DLL = "C:\Program Files (x86)\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
# load the assembly
[void] [Reflection.Assembly]::LoadFile($EXCHANGE_WEB_SERVICE_DLL)
# set ref to exchange
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
# use first option if you want to impersonate, otherwise, grab your own credentials
$s.Credentials = New-Object Net.NetworkCredential($username, $password, $domain)
# discover the url from your email address
$s.AutodiscoverUrl($email)
# get a handle to the inbox
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
$MailboxRootid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root, $email) # selection and creation of new root
$MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$MailboxRootid)
$fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(100) #page size for displayed folders
$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep; #Search traversal selection Deep = recursively
$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::Displayname,$NAME_OF_ARCHIVE_FOLDER_IN_MAILBOX) #for each folder in mailbox define search
$findFolderResults = $MailboxRoot.FindFolders($SfSearchFilter,$fvFolderView)
$ArchiveFolder = ""
# This next loop successfully finds my folder, but it is an inefficient way
# to do it. It's ok, because there's not that many folders, but there's tens
# of thousands of emails to search through in the folder itself, and that will
# need a more efficient search.
foreach ($Fdr in $findFolderResults.Folders)
{
$theDisplayName = $Fdr.DisplayName
if($theDisplayName -eq $USER_DEFINED_FOLDER_IN_MAILBOX)
{
$ArchiveFolder = $Fdr
}
}
# Now to actually try and search through the emails in my $ArchiveFolder (the hard way)
$textToFindInSubject = "TEST"
$emailsInFolder = $ArchiveFolder.FindItems(9999) # <-- Successfully finds ALL emails with no filtering, requiring iterative code to find the ones I want.
foreach($individualEmail in $emailsInFolder.Items)
{
if($individualEmail.Subject -match "$textToFindInSubject")
{
# found the email i want - but a super inefficient
# way to do it
echo "Successfully found the email!"
}
}
# Attempt 1 to get the emails with a more refined search
$emailSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$textToFindInSubject)
$emailsInFolder1 = $ArchiveFolder.FindItems($emailSearchFilter) # <-- Fails to return an object
# Attempt 2 to get the emails with a more refined search
$iv = new-object Microsoft.Exchange.WebServices.Data.ItemView(2000)
$emailsInFolder2 = $s.FindItems($ArchiveFolder, $emailSearchFilter, $iv) # <-- Also fails to return an object
echo "Done."
Thanks heaps :-)
I figured it out. Here are the lines of code that work [when appended to the initial code]
$searchfilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$textToFindInSubject)
$itemView = new-object Microsoft.Exchange.WebServices.Data.ItemView(999)
$searchResults = $s.FindItems($ArchiveFolder.ID, $searchfilter, $itemView)
foreach($result in $searchResults)
{
$subj = $result.Subject
echo "Subject: $subj"
}
This EWS script lists all folders, including custom ones. I'm running this on our Exchange 2010 SP1 server:
Import-Module -Name "C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\Owa\Bin\Microsoft.Exchange.WebServices.dll"
$userEmail = "email.address#domain.com"
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
$service.UseDefaultCredentials = $true
$service.AutoDiscoverUrl($userEmail)
$view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(100)
$view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.Webservices.Data.BasePropertySet]::FirstClassProperties)
$view.PropertySet.Add([Microsoft.Exchange.Webservices.Data.FolderSchema]::DisplayName)
$view.Traversal = [Microsoft.Exchange.Webservices.Data.FolderTraversal]::Deep
$findResults = $service.FindFolders([Microsoft.Exchange.Webservices.Data.WellKnownFolderName]::MsgFolderRoot, $view)
# List all folders
$findResults | select displayname
I want to add a App-Webpart like a Custom List which is already in Sharepoint to a Page using PowerShell. How can I do this?
This should do the job...
$WebUrl = 'Your Site\Web Url'
Add-PSSnapin "Microsoft.SharePoint.Powershell"
$SPWeb = Get-SPWeb $WebUrl
$oWebPartPage = $SPWeb.GetFile("SitePages/Test.aspx") # Url of Page where webpart should be added
$oWebPartPage.Checkout()
$oWebPartManager = $oWebPartPage.GetLimitedWebPartManager([System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
$list = $SPWeb.Lists["YourListName"] # Name of the list
$oWebPartView = New-Object "Microsoft.SharePoint.WebPartPages.ListViewWebPart"
$oWebPartView.ListName = $list.ID.ToString("B").ToUpper()
$oWebPartView.ViewType = "None"
$oWebPartView.ViewGuid = ""
$oWebPartManager.AddWebPart($oWebPartView,"RightZone",2)
$oWebPartManager.SaveChanges($oWebPartView)
I have a script that automates the a Visio diagram, i based my script on the official Office site: http://gallery.technet.microsoft.com/office/f77fb025-11ee-48f3-8409-9bb567a63fc3
Well to be honest i have no idea how to retrieve the values of the "shape data", this shape data is for example (Serial number, Building, Location, etc...) from the pc stencil.
I want to add and revise this values programatically, i ve checked the object model reference but without luck.
Can someone help me?
here is the code, it opens a visio document and adds a pc stencil to the drawing.
$application = New-Object -ComObject Visio.Application
$application.visible = $true
$documents = $application.Documents
$document = $documents.Add("Basic Network Diagram.vst")
$pages = $application.ActiveDocument.Pages
$page = $pages.Item(1)
$ComputerStencil = $application.Documents.Add("Computers and Monitors.vss")
$pc = $ComputerStencil.Masters.Item("PC")
$shape1 = $page.Drop($pc, 2.2, 6.8)
$shape1.Text = "Some text...."
Thanxs for your time!!
The Visio Automation library may help you:
Here's an example of how you can use it in C#. Using it in PowerShell should not be difficult.
var app = new IVisio.Application();
var doc = app.Documents.Add("");
var page = doc.Pages[1];
var shape1 = page.DrawRectangle(1, 1, 3, 4);
VisioAutomation.CustomProperties.CustomPropertyHelper.Set(shape1,"Hello","World");
var props = VisioAutomation.CustomProperties.CustomPropertyHelper.Get(shape1);
Using the Visio PowerShell Module, the code will look something like this:
Set-StrictMode -Version 2
$ErrorActionPreference = "Stop"
Import-Module Visio
$app= New-VisioApplication
$doc = New-VisioDocument
$stencil_net = Open-VisioDocument "Basic Network Diagram.vst"
$stencil_comp = Open-VisioDocument "Computers and Monitors.vss"
$pc_master = Get-VisioMaster "PC" $stencil_comp
$shapes = New-VisioShape -Masters $pc_master -Points 2.2,6.8
Set-VisioText "Some Text..."
Set-VisioCustomProperty -Name "prop1" -Value "val1"
Set-VisioCustomProperty -Name "prop2" -Value "val2"
$shapedata_col = Get-VisioCustomProperty -Shapes $shapes
foreach ($shapedata in $shapedata_col)
{
Write-Host "--------------------------------------"
Write-Host Name $shapedata.Name
Write-Host Type $shapedata.Type
Write-Host Value $shapedata.Value
Write-Host Prompt $shapedata.Prompt
Write-Host Ask $shapedata.Ask
Write-Host Calendar $shapedata.Calendar
Write-Host Format $shapedata.Format
Write-Host Invisible $shapedata.Invisible
Write-Host Label $shapedata.Label
Write-Host LangId $shapedata.LangId
Write-Host ShapeID $shapedata.ShapeID
Write-Host SortKey $shapedata.SortKey
}
At the bottom you can see how to set and retrieve shape data.
You could also export the drawing as html, then parse the resulting data.xml.
I'm trying to develop a powershell script to help with AD Group Membership management. We have a handful of large groups (30k-60k+ objects) that we want to update with data from another system.
The script loads the objects that should be in the group from a text file. Each object then has to located in AD using a System.DirectoryServices.DirectorySearcher. After that each object is added to the group membership.
The script spends some 80% of its time looking up each object, is there a bulk way to find objects in AD with powershell?
Thanks!
This is the fast way to query AD that I found in my experience, you need to change the query to find specific objects, in this code you'll find all user/person object in $objRecordSet.
$Ads_Scope_SubTree = 2
$objConnection = new-Object -com "ADODB.Connection"
$objCommand = new-Object -com "ADODB.Command"
$objConnection.Provider = "ADsDSOObject"
$objConnection.Open( "Active Directory Provider")
$objCommand.ActiveConnection = $objConnection
$objCommand.Properties.Item("Page Size").value = 1000
$objCommand.Properties.item("Searchscope").value = $Ads_Scope_SubTree
$objCommand.CommandText = "Select Name From 'LDAP://DC = int, DC= my, DC = local' Where objectCategory = 'Person'"
$objRecordSet = $objCommand.Execute()
$objRecordSet.RecordCount
More info here
You perhaps can try System.DirectoryServices.Protocols (S.DS.P) the native (non managed) version is quite efficient.
Here is a PowerShell starting script :
# ADDP-Connect.PS1
Clear-Host
# Add the needed assemblies
Add-Type -AssemblyName System.DirectoryServices.Protocols
# Connexion
$serverName = "WM2008R2ENT"
$ADDPConnect = New-Object System.DirectoryServices.Protocols.LdapConnection $serverName
$userName = "JPB"
$pwd = "PWD"
$domain = "Dom"
$ADDPConnect.Credential = New-Object system.Net.NetworkCredential -ArgumentList $userName,$pwd,$domain
# Create a searcher
$searchTargetOU = "dc=dom,dc=fr"
$searchFilter = "(samAccountName=user1)"
$searchScope = [System.DirectoryServices.Protocols.SearchScope]::Subtree
$searchAttrList = $null
foreach($user in "user1","user2","user3")
{
$searchFilter = "(samAccountName=$user)"
$searchRequest = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $searchTargetOU,$searchFilter,$searchScope,$searchAttrList
$searchResponse = $ADDPConnect.SendRequest($searchRequest)
foreach($searchEntries in $searchResponse.Entries)
{
$searchEntries.DistinguishedName
}
}
If you start seeing timeout issues then set the timeout parameter appropriately like shown below
$ADDPConnect = New-Object System.DirectoryServices.Protocols.LdapConnection $serverName
$ADDPConnect.Timeout = "1000"
The below can help if you see timeout issues during execution
$ADDPConnect = New-Object System.DirectoryServices.Protocols.LdapConnection $serverName
$ADDPConnect.Timeout = "1000"