Not able to update list field properties using sharepoint powershell - sharepoint

How do I use PowerShell to update list field properties? When I try the following:
$site = Get-SPSite -Identity "http://vikas:26112/"
$web= $site.OpenWeb()
$spList = $web.GetList("/Lists/Support Links")
$spFieldType = [Microsoft.SharePoint.SPFieldType]::Text
$spList.Fields.Add("FirstName",$spFieldType,$false)
$spList.Fields[“FirstName”].Description = “My FirstName Field”
$spList.Fields[“FirstName”].Required=$true
$spList.Fields["FirstName"].EnforceUniqueValues=$true
$spList.update()
$web.Dispose()
After executing this FirstName field is added to list but properties of this field remains unchanged:
Description =""
Required=false
EnforceUniqueValues=false

The problem is that you are not updating the field and that indexer is returning different instances each time you use it. You must store the instance of the field in some variable, then change it, then update it.
Change your code like this:
$site = Get-SPSite -Identity "http://vikas:26112/"
$web= $site.OpenWeb()
$spList = $web.GetList("/Lists/Support Links")
$spFieldType = [Microsoft.SharePoint.SPFieldType]::Text
$spList.Fields.Add("FirstName",$spFieldType,$false)
$field = $spList.Fields[“FirstName”]
$field.Description = “My FirstName Field”
$field.Required=$true
$field.EnforceUniqueValues=$true
$field.update()
$web.Dispose()

Related

Need to apply an if condition based on a check in Powershell

I am new to Powershell. I am actually getting the details of the azure data factory linked services but after get I need to use contains to check if the element exists. In python I would just check if string in a list but powershell not quite sure. Please check the code below.
$output = Get-AzDataFactoryV2LinkedService -ResourceGroupName $ResourceGroupName -DataFactoryName "xxxxxxxx" | Format-List
The output of the below is :
sample output given below
LinkedServiceName : abcdef
ResourceGroupName : ghijk
DataFactoryName : lmnopq
Properties : Microsoft.Azure.Management.DataFactory.Models.AzureDatabricksLinkedService
So now I try to do this:
if ($output.Properties -contains "Microsoft.Azure.Management.DataFactory.Models.AzureDatabricksLinkedService") {
Write-Output "test output"
}
But $output.Properties gives us the properties of that json.
I need to check if "Microsoft.Azure.Management.DataFactory.Models.AzureDatabricksLinkedService" exists in output variable and perform the required operations. Please help me on this.
The -contains operator requires a collection and an element. Here's a basic example of its proper use:
$collection = #(1,2,3,4)
$element1 = 5
$element2 = 3
if ($collection -contains $element1) {'yes'} else {'no'}
if ($collection -contains $element2) {'yes'} else {'no'}
What you've done is ask PowerShell to look in an object that isn't a collection for an element of type [string] and value equal to the name of that same object.
What you need to do is inspect this object:
$output.Properties | format-list *
Then once you figure out what needs to be present inside of it, create a new condition.
$output.Properties.something -eq 'some string value'
...assuming that your value is a string, for example.
I would recommend watching some beginner tutorials.

Evaluate variable(s) inside string passed escaped to function in PowerShell

I have a PowerShell function like this (I have simplified it here to make it more understandable):
Function QueryList
{
param(
[Parameter(Mandatory=$true,Position=1)]
[Microsoft.SharePoint.SPList] $list
[Parameter(Mandatory=$true,Position=2)]
[string] $camlQuery
)
$itemsQry = New-Object Microsoft.SharePoint.SPQuery
$itemsQry.Query = $camlQuery
$itemsQry.ViewFieldsOnly = $false
$itemsQry.RowLimit = 0
$itemsQry.ViewAttributes = "Scope='Recursive'"
return $list.GetItems($itemsQry)
}
Function MigrateList
{
param(
[Parameter(Mandatory=$true,Position=1)]
[Microsoft.SharePoint.SPList] $list,
[Parameter(Mandatory=$true,Position=2)]
[string] $matchingItemsQuery
)
foreach ($listItem in $list.Items)
{
# get items using the query (how to inject '$listItem' into query string?)
$targetItem = QueryList -list $list -camlQuery $matchingItemsQuery
# do something with matching items
...
}
}
# main script
$matchingItemsQuery = "<Where><Eq><FieldRef Name='Title' /><Value Type='TEXT'>`$(`$listItem[`"Title`"])</Value></Eq></Where>"
$targetItems = MigrateList -list $listXy -matchingItemsQuery $matchingItemsQuery
As you can see, I want to query some items from a list, matching a given criteria. As the criteria changes from list to list I want to be able to pass the query to the function, inside the query there is a reference to the variable that will only exist in the 'MigrateList' function (here: $listItem).
As it is now, the variable will of course not be evaluated to the objects value ("Title" column value of $listItem) as it is passed as a string, as the '$' are escaped (which is needed to pass the query to the function).
I know it is maybe not the nicest construct but it would get the job done. So how could I change the script that the passed query string will be injected with the $listItem object (in this case, column value)?
Thank you for the comments, especially #TheIncorrigible1 for the tip regarding using a scriptblock, which I (successfully) tried to implement.
I got it to work with this:
Function MigrateList
{
param(
[Parameter(Mandatory=$true,Position=1)]
[Microsoft.SharePoint.SPList] $list,
[Parameter(Mandatory=$true,Position=2)]
[scriptblock] $itemMatchQuerySb
)
foreach ($listItem in $list.Items)
{
# get items using the query (how to inject '$listItem' into query string?)
$matchingItemsQuery = (. $itemMatchQuerySb)
$targetItem = QueryList -list $list -camlQuery $matchingItemsQuery
# do something with matching items
...
}
}
# main script
$matchingItemsQuerySb = [scriptblock]::Create("echo ""<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>`$(`$listItem[`"Title`"])</Value></Eq></Where>""")
$targetItems = MigrateList -list $listXy -matchingItemsQuery $matchingItemsQuery

Alternative to foreach items in a sharepoint list

I MODIFIED THE CAML AND IT'S NOW WORKING AND DOES NOT LOOP THROUGH ALL THE ITEMS IN A LIST.
I am looking for list items where workflow status equal "Error Occurred". I have the following code and it's working fine. However, there are 124,000 items in my list and the code goes through each item in the list. Is there a way to limit this to items where workflow status (workflow name is "Archive Data") is "Error Occurred". Please suggest. I added following CAML and changed the code but it still returns all the records. I tested the CAML with u2u and it returns 144 records. I added write-host to get a count and commented out the foreach for test.
# Terminates all workflow in a give list
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$web = Get-SPWeb "http://inside.nov.com/sales/SouthEast"
$web.AllowUnsafeUpdates = $true
# $list name is list display name
$list = $web.Lists["New Orders"]
$CAML = '<Where>
<Eq>
<FieldRef Name="ArchiveData" />
<Value Type="WorkflowStatus">3</Value>
</Eq>
</Where>'
$query = new-object Microsoft.SharePoint.SPQuery
$query.Query = $CAML
$listitems = $list.GetItems($query)
Write-Host "Count: " $listitems.Count
#foreach ($item in $listItems)
#{
# foreach ($wf in $item.Workflows)
# {
# #Cancel Workflows
# [Microsoft.SharePoint.Workflow.SPWorkflowManager]::CancelWorkflow($wf)
# }
#}
$web.Dispose()
I updated the original code and it's working. The keyword "Query" dont need to be in CAML when using SPQuery object. The SPQuery automatically wraps the CAML with keyword.
Thanks

Powershell: Loading all items/properties into a new object

Take this code:
$logged_on_user = get-wmiobject win32_computersystem | select username
If I want to output the value into a new string I'd do something like:
$A = $logged_on_user.username
However, if I do the following:
$logged_on_user = get-wmiobject win32_computersystem | select *
..to try to assign all the values to a new "object", do I?:
$logged_on_user.items
$logged_on_user.value
$logged_on_user.text
$logged_on_user.propertry
I've tried them all and they don't work.
Anybody got any ideas?
Thanks
P.S. I think I may have got the title of this question wrong.
In your example:
$logged_on_user = get-wmiobject win32_computersystem | select username
creates a new PSCustomObject with a single property - username. When you do the following:
$A = $logged_on_user.username
you are assigning the return value of the PSCustomObject's username property to a variable $A. Because the return type of the username property is a string, $A will also be a string.
When executing the following:
$cs = get-wmiobject win32_computersystem
If you assign $cs to a new variable like in the following:
$newVariable = $cs
Then $newVariable will reference the same object $cs does, so all properties and methods that are accessible on $cs will also be accessible on $newVariable.
If you don't specify any properties or call any methods on an object when assigning a return value to another variable, then the return value is the object itself, not the return value of one of the object's properties or methods.
Additional info, but not directly related to the question:
When you pipe the output of get-wmiobject to select-object, like in the following:
$cs = get-wmiobject win32_computersystem | select-object *
The variable $cs is of type: PSCustomObject as opposed to ManagementObject (as it is when you do not pipe to Select-Object) which has all of the same properties and their values that the ManagementObject that was piped in did.
So, if you only want the property values contained by the ManagementObject, there is no need to pipe the output to Select-Object as this just creates a new object (of type PSCustomObject) with the values from the MangementObject. Select-Object is useful when you either want to select a subset of the properties of the object that is being piped in, or if you want to create a new PSCustomObject with different properties that are calculated through expressions.
I'm not sure if you're asking about copying the results of Get-WmiObject or PowerShell objects in general. In the former case, Get-WmiObject returns instances of the ManagementObject class, which implements the ICloneable interface that provides a Clone method. You can use it like this...
$computerSystem = Get-WmiObject -Class 'Win32_ComputerSystem';
$computerSystemCopy = $computerSystem.Clone();
After the above code executes, $computerSystem and $computerSystemCopy will be identical but completely separate ManagementObject instances. You can confirm this by running...
$areSameValue = $computerSystem -eq $computerSystemCopy;
$areSameInstance = [Object]::ReferenceEquals($computerSystem, $computerSystemCopy);
...and noting that $areSameValue is $true and $areSameInstance is $false.

PowerShell - New-SPWeb with UniquePermissions

I want to create a new SPWeb with PowerShell.
My code creates the site and add the group to the site but not the user "TestUser1".
The test\testuser1 belongs not to the TestGroup1 and get intepend permissions.
$web = New-spweb http://http:/mysharepointurl/site/web -Template "STS#0" -UniquePermissions
$user = $web.EnsureUser('test\testuser4')
$web.Users.AddUser($user, "Full") #Not working, Add a existing User
$newGroup = $web.SiteGroups["TestGroup6"] #Working, Add a existing Group
$web.Roles["Full"].AddGroup($newGroup)
Have you tried
$web.Users.Add -or- $web.AllUsers.Add
public void Add(
string loginName,
string email,
string name,
string notes
)
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spusercollection.add.aspx
You are using New-SPWeb, so that means you need to be adding users to the SPWeb.
$web.SiteUsers is the site collection group
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.siteusers.aspx
You should use
$web.Users
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.users.aspx
My working solution:
$web = Get-SPWeb "http://http:/mysharepointurl/site/web"
$user = $web.AllUsers["test\testuser1"]
$roledef = $web.RoleDefinitions["Vollzugriff"]
$roleass = New-Object Microsoft.SharePoint.SPRoleAssignment($user)
$roleass.RoleDefinitionBindings.Add($roledef)
$web.RoleAssignments.Add($roleass)
$web.Update()
Thanks for the support!

Resources