If that checks SiteUrl value exists in array using PnP

Brass Contributor

I'm trying to add items to an SPO list only if the item is not there already:

 

$ListItems = Get-PnPListItem -List $List
ForEach($Hub in $HubSites)
{
    $HubSiteId = $Hub.ID.GUID
    ForEach($Site in $Sites)
    {
        $AssociatedHubSiteID = $Site.HubSiteId.Guid
        If ( ($AssociatedHubSiteID -eq $HubSiteId) -and ($Hub.SiteUrl -ne $Site.Url) )
        {
            $ReportEntry = "" | Select-Object Hub,SiteUrl
            $ReportEntry.Hub = $Hub.SiteUrl 
            $ReportEntry.SiteUrl = $Site.Url 
            $Report += $ReportEntry 
            #$item = $ListItems | Where-Object { $_.FieldValues.SiteUrl -eq $Site.Url }
            #if ($Site.Url -ne $item[0].FieldValues.SiteUrl) {
            if ($Site.Url -notin $ListItems.FieldValuesAsText.SiteUrl) {
                Add-PnPListItem -List $List -Values @{"Hub" = $Hub.SiteUrl; "SiteUrl" = $Site.Url}
            }

 

If think the issue may be with line 16? I've left in my attempts as comment outs on line 14 and 15.

12 Replies

@CardinalNight 

 

Hi, Thomas.

 

If we run with your assumption that the issue is with line 16, then -notin is probably not the appropriate operator. Try the following instead:

 

if ($ListItems.FieldValuesAsText.SiteUrl -notcontains $Site.Url) {

 

Some diagnostic information that would help is:

 

  • The results from running:
    $ListItems.FieldValuesAsText.SiteUrl.pstypenames;

 

  • The results from running:
    $ListItems.FieldValuesAsText.SiteUrl | Select-Object -First 5;

 

Basically, I'm looking for some type information and sample data given I don't work with SharePoint and cannot replicate your tests.

 

Cheers,
Lain

As a quick clarification after having gone and fact-checked myself on what I thought I remembered about -notin (where I thought it only behaved against collections), it turns out I recalled incorrectly as it works against arrays as well. This means the suggestion I made about -notcontains likely won't make any difference.

 

That said, the diagnostic commands are still useful since I have no idea what the types and example data look like.

 

Cheers,

Lain

Hi, how would enter these type checks in the script? Can you provide please. When I run one of the provided lines, then run $listItems it just shows:
Id         Title      GUID
--         -----      ----
280                   6185d296-1919-4179-g654-02ae6bcec4d9
281                   1a4efa4f-9f82-4543-b2345-26f459ec0b45
etc....

@CardinalNight 

 

Just the first line from your script and then the following two lines added after it:

 

$ListItems = Get-PnPListItem -List $List;
$ListItems.FieldValuesAsText.SiteUrl.pstypenames;
$ListItems.FieldValuesAsText.SiteUrl | Select-Object -First 5;

 

Cheers,

Lain

I'm getting:
Id Title GUID
-- ----- ----
345 3re5761be-7187-4338-822c-c471bd7eca18
346 a6c90218-112f-41d6-8673-4787a3b5c50e
347 7f989014-499b-4f45-96ea-59ce36g25dfcf

@CardinalNight 

 

I might have to leave this for someone who uses SharePoint and the PnP module, as I can't make any sense of that output.

 

If the three commands from above were just being run from the command line, there should have been two sets of output:

 

  1. Output from the ".pstypenames" command; then
  2. Output from the ".SiteUrl | Select-Object" command.

 

It seems the first output is not being produced at all, which I would only expect if it were being run from within a script or function, while the second output is either not being produced, or if what you're seeing is actually it, then it is quite different to what I'd expected based on the property name (I'd expected an array or collection of strings).

 

That said, if the results you are seeing are actually the rows from ".SiteUrl" then that may well explain why $Site.Url is not being found in that set, though there's no point in my expanding on that.

 

@Harm_Veenstra, is this something you're able to reproduce using the PnP module? If so, perhaps you can pick this up.

 

I'm getting the impression that the -notin comparison from line 16 of the original script is failing because one or both sides of the operator are complex types - which won't work. It needs to be brought back to a simple type comparison.

 

Cheers,

Lain

I'm trying to reverse engineer the part of the script and adding things to a SharePoint site in my tenant... But I'm not a SharePoint expert, so I don't understand the Hub component. Perhaps I need more parts of the script and a more filled SharePoint site to test this?

@Harm_Veenstra The full sanitized script:

Connect-PnPOnline -Url "https://myCompany-admin.sharepoint.com" -Interactive

# Output location for CSV
$Report = @()
Write-Host "Getting list of all hubsites..."
# Get all the hubsites
$HubSites = Get-PnPHubSite
# Get all sites, exluding sites without a connected hub by filtering them out client side
Write-Host "Getting list of all sites excluding sites without a connected hub..."
$Sites = Get-PnPTenantSite | ? {$_.HubSiteId.Guid -ne "00000000-0000-0000-0000-000000000000"}
Write-Host "Getting the target SPO site to create items..."
$connection = Connect-PnPOnline -Url "https://myCompany.sharepoint.com/sites/HubSiteMap" -Interactive
#$web = Get-PnPWeb -Connection $connection
$List = Get-PnPList "Sites" -Connection $connection
$ListItems = Get-PnPListItem -List $List
$ListItems = Get-PnPListItem -List $List;
$ListItems.FieldValuesAsText.SiteUrl.pstypenames;
$ListItems.FieldValuesAsText.SiteUrl | Select-Object -First 5;
$ListItems #This line is a test to see what appears (it's that table of Guids)

# Iterate through each hub
ForEach($Hub in $HubSites)
{
    # Get the ID of the Hubsite
    $HubSiteId = $Hub.ID.GUID
    # Iterate through each site collection
    ForEach($Site in $Sites)
    {
        # Get the Associated Hubsite ID for this site
        $AssociatedHubSiteID = $Site.HubSiteId.Guid
        # If the associated HubSite ID of this site equals the hubsite id of the hub we are currently checking
        # AND the site url of this site does not equal the hubsite url of the hub we are currently checking
        # then we can create an entry.
        If ( ($AssociatedHubSiteID -eq $HubSiteId) -and ($Hub.SiteUrl -ne $Site.Url) )
        {
            $ReportEntry = "" | Select-Object Hub,SiteUrl 
# Initialize an empty ReportEntry object, add Hub and SiteURL properties to the object
            $ReportEntry.Hub = $Hub.SiteUrl 
#Add the hub URL to the Hub property of the object
            $ReportEntry.SiteUrl = $Site.Url #Add the Site 
URL to the SiteUrl property
            $Report += $ReportEntry # Add the ReportEntry object to the Report array
            #$item = $ListItems | Where-Object { $_.FieldValues.SiteUrl -eq $Site.Url }
            #if ($Site.Url -ne $item[0].FieldValues.SiteUrl) {
            if ($Site.Url -notin $ListItems.FieldValuesAsText.SiteUrl) {
                Add-PnPListItem -List $List -Values @{"Hub" = $Hub.SiteUrl; "SiteUrl" = $Site.Url}
            }
        }
    }
}

The two columns in the SharePoint Online list are Hub and SiteUrl. It's successfully adding to the list with no problems but of course I need the If at the bottom to stop it from adding if those SiteUrl's are already there.

I have to create some SharePoint things in my tenant for this to work... Don't have hub sites etc :)
Any update on this?
I don't have time to dive into it for the next few weeks. My SharePoint knowledge isn't that good, so it takes time for me to create enough things in my SharePoint environment to test this.
I appreciate it.