0

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

Patric
  • 2,789
  • 9
  • 33
  • 60
  • Perhaps you should look into string concatenation instead of expansion-within-string to construct the query string? – Jeff Zeitlin Nov 21 '17 at 14:14
  • I've reread your question a few times and cannot understand what it is you want to do here. Maybe try rewording it? Or give a pseudo code example of how you'd like this to work so we can help you get there? – FoxDeploy Nov 21 '17 at 14:24
  • 1
    You could utilize script blocks. They are not evaluated until you execute them with the dot operator (`.`) or call operator (`&`) – Maximilian Burszley Nov 21 '17 at 14:27
  • Or use numeric placeholders and the formatting operator `"B{0}gel" -f "a"`. If you _really_ want delayed variable expansion then this is a dupe: https://stackoverflow.com/questions/15168705/how-to-delay-expansion-of-variables-in-powershell-strings – Matt Nov 21 '17 at 14:41
  • @TheIncorrigible1 I'm not quite sure I understand how this can be implemented. Do I have to call ([scriptblock]::Create($matchingItemsQuery)) inside the MigrateList function? I tried, also with '&' and '.' but was not able that it returns the string value. – Patric Nov 21 '17 at 14:50
  • @Patric `$matchingItemsQuery = { ... }` then in your function, call it like `$StringItem = & $matchingItemsQuery` – Maximilian Burszley Nov 21 '17 at 16:14

1 Answers1

0

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
Patric
  • 2,789
  • 9
  • 33
  • 60