Share via


Cannot convert system.object to the type system collection idictionary

Question

Saturday, April 22, 2017 12:05 AM

Hi guys,

I'm working on iterating through our SharePoint Online 200 sites and while i'm iterating I need to get Metadata of folders and files in specific document library.

I have all the appropriate syntax together to give me what I want.

I'm trying to put all the properties of the files/folders metadata into an object called $Properties

It appears that I'm instantiating my object incorrectly.

How can I fix this issue? also I need to increment the metadata input into my object I haven't done that before I assumed that I need to put += before could you please advise?

Here is my code

$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)


#$DocStructure = "C:\Temp\Document Library Folders Structure.csv"
$HotelSitesFile = "C:\Temp\HotelSites.csv"
$SPOFoldersFile = "C:\Temp\NightAuditPackFolders.csv"
$LogFile = "C:\Temp\FoldersAndFilesStructure.Log"

$HotelSites = Get-Content -Path $HotelSitesFile

$Properties = @()

ForEach($HotelSite In $HotelSites)
{
    if($HotelSite.Substring(0,5) -eq "https")
    {
        Try {
            Connect-PnPOnline -Url $HotelSite -Credentials $Credentials
            
            Write-Host $HotelSite -ForegroundColor Green

            $SPOFolders = Get-Content -Path $SPOFoldersFile
            ForEach($SPOFolder in $SPOFolders)
            {
                Write-Host $SPOFolder -ForegroundColor Yellow
                $MetaDatas = Get-PnPFolderItem -FolderSiteRelativeUrl $SPOFolder -ErrorAction SilentlyContinue -ErrorVariable ProcessError 
            
                ForEach($MetaData In $MetaDatas)
                {
                    $Properties += @{SiteUrl = $HotelSite;FolderSiteRelativeUrl = $SPOFolder;MetaDataGUID = $MetaData.UniqueId;MetaDataName = $MetaData.Name}
                                    #MetaDataParentFolder = $MetaData.ParentFolder
                                    #MetaDataItemCount = $MetaData.ItemCount
                                    #MetaDataServerRelativeUrl = $MetaData.ServerRelativeUrl
                                    #MetaDataTimeCreated = $MetaData.TimeCreated
                                    #MetaDataTimeLastModified = $MetaData.TimeLastModified}                
                }
            }            
        } Catch {
            Write-Verbose "Error occurred at Hotel Site $HotelSite"
                    
        } Finally {
            $PSObject = New-Object -TypeName PSObject -Property $Properties
            Write-Output $PSObject         
        }        
    }
}

Here is the print screen link Syntax

Thank you in advance for your help

All replies (5)

Monday, April 24, 2017 3:20 PM ✅Answered

I am not being funny or smart.  Your code is almost impossible to follow and you have not asked a question that makes much sense.  YOU seem to be asking how to create a set of objects.  In PowerShell you will need to generate a hash that can be set to default values.  This hash can then be output consistently.

You have many lines which are totally unnecessary and you are not generating consistent objects which will cause issues.  In your solution the remnants of a previous set of assignments will be retained which will give you bad results on any error.  Even in C# or VB this would be a faulty design and is an mistake that new programmers make regularly.

Note also that you are looping through a set of results and overwriting the contents of your object on each loop so only the last result will be retained.

You are copying things you have seen from old PS1 code hence the use of "Add-Member" instead of using a hash.  A hash will clean up your code and will make it easier to generate fresh objects.

You are tryin to use Try/Catch but have set a command to "SilentlyContinue" which defeats the purpose of Try/Catch so no errors will ever be detected.

Why are you using a CSV and then using Get-Content on it.  If it is a CSV then use Import-Csv.  If it is not a CSV then you might want to change the file extension to prevent ongoing confusion.

I know you are learning PS but the code design concepts are still the same as in other Net languages.  It is the syntax and features that change.  Also PowerShell allows us much simpler mechanisms to use because it is an interpreted system and not a compiled system.

I suggest sitting down and rethinking how your code executes then simplifying the approach.  It will help you learn about code design and it will help you to learn PowerShell.

\(ツ)_/


Saturday, April 22, 2017 12:35 AM

We cannot read your blurry images.  Please post a specific issue.  We cannot debug your code for you for obvious reasons.

\(ツ)_/


Saturday, April 22, 2017 4:45 AM

The following line makes no senseand is the source of your issues.

$Properties += @{SiteUrl = $HotelSite;FolderSiteRelativeUrl = $SPOFolder;MetaDataGUID = $MetaData.UniqueId;MetaDataName = $MetaData.Name}
 

It should look like this:

[pscustomobject]@{ 
    SiteUrl = $HotelSite
    FolderSiteRelativeUrl = $SPOFolder
    MetaDataGUID = $MetaData.UniqueId
    MetaDataName = $MetaData.Name 
}

Its code.  time to learn hos to code.  Don't blindly copy things without understanding how they work.

The link you posted cannot be viewed.

\(ツ)_/


Monday, April 24, 2017 1:35 PM | 2 votes

I don’t understand why do you have to be judgmental?

First of all, I didn’t copy from the internet, I have been learning Powershell from PluralSight.

Second, I come from.NET development so it’s a matter of time for me to start adopting PowerShell Syntax.

 

You are a moderator of this forum, that means you don’t have to humiliate and be smart ass with your remarks.

If you don’t feel like doing this job just hand it to someone who is more passionate about guiding people with PowerShell.

 

Speaking of guiding, here is the solution, I fixed it myself and I’m posting it here so no one else need to put up with the Moderator smart ass remarks!

Clear-Host 

$User = "[email protected]"
$File = "C:\Temp\MyPasswordNew.txt" 
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $File | ConvertTo-SecureString)

$HotelSitesFile = "C:\Temp\HotelSites.csv"
$SPOFoldersFile = "C:\Temp\NightAuditPackFolders.csv"

$MetaDataObjectModel = New-Object PSObject
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name HotelSiteUrl -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name FolderSiteRelativeUrl -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataGuid -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataName -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataParentFolder -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataItemCount -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataServerRelativeUrl -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataTimeCreated -Value $null 
$MetaDataObjectModel | Add-Member -MemberType NoteProperty -Name MetaDataTimeLastModified -Value $null 


$HotelSites = Get-Content -Path $HotelSitesFile

[System.Collections.ArrayList]$MetaDataProperties = @()

ForEach($HotelSite In $HotelSites)
{
    if($HotelSite.Substring(0,5) -eq "https")
    {
        Try {
            Connect-PnPOnline -Url $HotelSite -Credentials $Credentials
            
            Write-Host $HotelSite -ForegroundColor Green

            $SPOFolders = Get-Content -Path $SPOFoldersFile
            ForEach($SPOFolder in $SPOFolders)
            {
                Write-Host $SPOFolder -ForegroundColor Yellow
                $MetaDatas = Get-PnPFolderItem -FolderSiteRelativeUrl $SPOFolder -ErrorAction SilentlyContinue 
            
                ForEach($MetaData In $MetaDatas)
                {
                    $MetaDataObject = $MetaDataObjectModel | Select-Object *
                    
                    $MetaDataObject.HotelSiteUrl = $HotelSite
                    $MetaDataObject.FolderSiteRelativeUrl = $SPOFolder
                    $MetaDataObject.MetaDataGuid = $MetaData.UniqueId
                    $MetaDataObject.MetaDataName = $MetaData.Name
                    $MetaDataObject.MetaDataParentFolder = $Metadata.ParentFolder 
                    $MetaDataObject.MetaDataItemCount = $MetaData.ItemCount
                    $MetaDataObject.MetaDataServerRelativeUrl = $MetaData.ServerRelativeUrl
                    $MetaDataObject.MetaDataTimeCreated = $MetaData.TimeCreated
                    $MetaDataObject.MetaDataTimeLastModified = $MetaData.TimeLastModified
                   
                    $MetaDataProperties.Add($MetaDataObject) | Out-Null
                                        
                }
            }            
        } Catch {            
            Write-Error "$($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)" 
                    
        } Finally {            
            Write-Output $MetaDataProperties          
        }        
    }
}



$MetaDataProperties | Export-Csv -LiteralPath C:\Temp\MetaDataProperties.csv -NoTypeInformation 


Codernater


Wednesday, November 7, 2018 12:00 PM

Thank you Cordenator - saved my day!

By the way, I fully support your argumentation regarding that bad behaviour of the moderator!