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

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

Related

JMeter ForEach controller with list of Objects not being iterated over

Following is my test plan. Where ForEach controller should loop through all the task Ids stored in user defined variable "userTaskIds". I tried defining list with
both def myList = [] and List<Object> listId = new ArrayList<Object>();. In both the case its failed to loop.
ForEach controller not looping with "userTaskIds" variable. Here i tried with/without "add "_" before number ?"
Following are debug sampler result and Log view panel
Log View
This is because ForEach Controller expects this:
userTaskIds_1
userTaskIds_2
...
And
userTaskIds_matchNr = number of occurences
So in your JSR223 script you need to do this in each loop iteration :
Replace responseJSON.each by
responseJSON.eachWithIndex {
it, iterationLoop ->
Then
vars.put("userTaskIds_"+(iterationLoop+1), ""+it.id)
where iterationLoop must start with 1 and be incremented.
and after loop:
vars.put("userTaskIds_matchNr", Integer.toString(myList.size()));

Pass a Microsoft.SharePoint.SPList to a function

I'm pretty new to powershell & sharepoint and i'm having hard time trying to create a function.
I'm trying to make a generic function to add new items into a SPList but i can't pass the SPList to the function.
Here is my function prototype:
function Add-IntoList([Microsoft.SharePoint.SPList] $List,[hashtable] $Columns)
{
... some code
}
And here is my call to the function:
$web = Get-Web("http://some_url/sandbox1") #It returns the Get-SPWeb
$test = #{"Title" = "Olympia"; "Body" = "Salem"}
Add-IntoList($web.Lists["Announcements"], $test)
And it doesn't work, i can't see why.
Here is the error powershell tells me:
Add-IntoList : Cannot process argument transformation on parameter 'List'. Cannnot convert the "System.Object[]" value of type "System.Object[]" to type "Microsoft.Sharepoint.SPList".
What am i doing wrong ?
Thanks in advance,
Nicolas
When you call the function, instead of calling it like:
Add-IntoList($web.Lists["Announcements"], $test)
call it like:
Add-IntoList $web.Lists["Announcements"] $test

Implement own method with multiple parameters in PowerShell

I want do create a custom object with a method that takes more than one parameter. I already managed to add a method that takes one parameter, and it seems to work:
function createMyObject () {
$instance = #{}
add-member -in $instance scriptmethod Foo {
param( [string]$bar = "default" )
echo "in Foo( $bar )"
}
$instance
}
$myObject = createMyObject
But every time I try to add a method with takes two parameters by simply adding another [string]$secondParam - clause to the param-section of the method, the invocation
$myObject.twoParamMethod( "firstParam", "secondParam" )
does not work. The error message in my language says something like "it is not possible to apply an index to a NULL-array".
Any hints? Thanks!
Something like this seems to work (at least in PowerShell v4)...
add-member -in $instance scriptmethod Baz {
param( [string]$bar = "default", [string]$qux = "auto" )
echo "in Baz( $bar, $qux )"
}
To call it, I did:
[PS] skip-matches> $myObject.Baz("Junk","Stuff")
in Baz( Junk, Stuff )
[PS] skip-matches> $myObject.Baz()
in Baz( default, auto )
Just adding a version of this that I got working.
function Demo ([ref]$var) {
$var.Value = 5
$var
}
[psobject] $changeMe = New-Object psobject
$changeMe = 0
$changeMe # Prints 0
$v = Demo([ref]$changeMe)
$changeMe # Prints 0, should print 5
To assigned a value to an object, you need to use the Value property of the reference object. Also, I instantiate an object instance and pass a reference to that.

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.

Not able to update list field properties using sharepoint powershell

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

Resources