0

I wrote a PowerShell script which will loop thru all the sites in the web application and add Field internalname and title to the HashTable. So i pass this HashTable from one function to another. But i get an error when executing the script. It says that the Object doenst have the ContainsKey method. So actually there is a problem when i pass HashTable it becomes an object and not HashTable anymore.

Anyone know how could i solve this? When i try to define the type of the object which is passed it just says that the object cannot be converted to HashTable.

Here is the script code that i use:

function Manage($hashTable, $webs)
{
    $hash=$hashTable
    foreach($spWeb in $webs)
    {   
        $spWebFields=$spWeb.Fields
        $hash=AddHashes($hash, $spWebFiels)

        $spWeb.Dispose()
    }
}

function AddHashes($hash, $fields)
{
    foreach($field in $fields)
    {
        $hasKey=$hash.ContainsKey($field.InternalName)
        if($hasKey -eq $false)
        {
            $hash.Add($field.InternalName, $field.Title)
        }
    }
    return $hash
}

foreach($sitecol in $sitecols) 
{ 
    Manage(@{}, $siteCol.AllWebs)

    $siteCol.Dispose()
}

1 Answer 1

2

I think the correct syntax for calling manage is :

Manage @{} $siteCol.allwebs.

If you use PowerShell ISE, and you breakpoint within Manage, I'm quite sure that $hashTable will be an array objects containing all the arguments.

In fact, your syntax is passing an array of object for the first argument, instead of passing arguments separately.

Here is the corrected version :

function Manage($hashTable, $webs)
{
    $hash=$hashTable
    foreach($spWeb in $webs)
    {   
        $spWebFields=$spWeb.Fields
        $hash=AddHashes $hash $spWebFiels

        $spWeb.Dispose()
    }
}

function AddHashes($hash, $fields)
{
    foreach($field in $fields)
    {
        $hasKey=$hash.ContainsKey($field.InternalName)
        if($hasKey -eq $false)
        {
            $hash.Add($field.InternalName, $field.Title)
        }
    }
    return $hash
}

foreach($sitecol in $sitecols) 
{ 
    Manage @{} $siteCol.AllWebs

    $siteCol.Dispose()
}

To avoid such issues, I'm use to use [CMDLetBinding()]. This allow me to name parameters and avoid some syntax weird issues :

function Manage
{
    [CmdLetBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [System.Collections.HashTable]$hashTable, 
        [Parameter(Mandatory=$true)]
        [Microsoft.SharePoint.SPWebCollection]$webs
    )
    $hash=$hashTable
    foreach($spWeb in $webs)
    {   
        $spWebFields=$spWeb.Fields
        $hash=AddHashes -hash $hash -fields $spWebFiels

        $spWeb.Dispose()
    }
}

function AddHashes
{
    [CmdLetBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [System.Collections.HashTable]$hash, 
        [Parameter(Mandatory=$true)]
        [Microsoft.SharePoint.SPFieldCollection]$fields
    )
    foreach($field in $fields)
    {
        $hasKey=$hash.ContainsKey($field.InternalName)
        if($hasKey -eq $false)
        {
            $hash.Add($field.InternalName, $field.Title)
        }
    }
    return $hash
}

foreach($sitecol in $sitecols) 
{ 
    $hash = @{}
    Manage -hashTable $hash -webs $sitecol.AllWebs

    $siteCol.Dispose()
}
2
  • Thanks you very much, you were right there was a problem with passing the parameters!
    – Shkipper
    Jun 21, 2012 at 8:50
  • As my primary language is C#, I made this mistake a few times :)
    – Steve B
    Jun 21, 2012 at 9:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.