Not able to fill empty array with data from function

Hi folks. i’m using Powershell to extract data values from sharepoint on-prem and into an empty array. So far it does not seem to work. Only when i use Write-Host, the output window shows the data i need. But $hashtable does not seem to capture any of the data i’m trying to pull. $hashtable.count is empty. What am i missing? Thank you

[pre]

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$Hashtable = @()

Function GetFiles($Folder)
{

foreach($file in $Folder.Files)
{
if($file.Name -like “.htm”){

Write-Host $file.Name
Write-Host $file.URL
$Hashtable += New-Object PSObject -Property @{‘filename’=$file.Name;‘fileURL’=$file.URL;}
}
}
#Loop through all subfolders and call the function recursively
foreach ($SubFolder in $Folder.SubFolders)
{
if($SubFolder.Name -ne “Forms”)
{
Write-Host “`t” -NoNewline
GetFiles($Subfolder)

}
}
}

#Get the Site collection
$Site= Get-SPSite “https://dev.mycompany.com/sites/Stuff
#Loop through all Sub Sites
foreach($Web in $Site.AllWebs)
{

Write-Host $web.Title

foreach($list in $Web.Lists)
{
#Filter Doc Libs, Eliminate Hidden ones
if(($List.BaseType -eq “DocumentLibrary”) -and ($List.Hidden -eq $false) )
{
GetFiles($List.RootFolder)
}
}
}

[/pre]

Do not have SharePoint to test, but you have the hashtable variable defined outside the function, so you should be getting errors about op_addition in the function. Try setting a variable to the foreach and you do not need the += operation. Also, if you want output inside the function, use Write-Verbose. Here is something to try:

function Get-SPFiles {
    [CmdletBinding()]
    param (
        $Folder
    )
    begin{}
    process {
        $files = foreach($file in $Folder.Files) {
            if($file.Name -like '*.htm*'){
                Write-verbose ('Processing file {0} at url {1}' -f $file.Name, $file.Url)
                New-Object PSObject -Property @{
                    FileName = $file.Name
                    FileUrl  = $file.URL
                }
            }
        }

        #Loop through all subfolders and call the function recursively
        foreach ($SubFolder in $Folder.SubFolders) {
            if($SubFolder.Name -ne 'Forms') {
                Write-verbose ('Processing folder {0}' -f $SubFolder.Name)

                Get-SPFiles($Subfolder)
 
            }
        }
    }
    end {
        $files
    }
}

Thanks so much Rob, you are a genius! From my original post, i have the bottom code to call the function. When i execute the entire set of code, it looks perfect in ISE output window, but i’m trying to Export to CSV the value of Write-Host “$($web.URL)” along with the $file.name and $file.URL.

The $web.URL, is the first portion of the full Sharepoint website URL. $file.URL is the second portion of the full Sharepoint URL.

Currently i have the Export-CSV cmdlet after Get-SPFiles($List.RootFolder) but it does not include the 1st critical value of $($web.URL), it only exports the $file.name and $file.URL. Hope my explanation is not too convoluted :slight_smile: Thank you again

 

[pre] #Get the Site collection
$Site= Get-SPSite “https://dev.mycompany.com/sites/Stuff
#Loop through all Sub Sites
foreach($Web in $Site.AllWebs)
{
Write-Host “$($web.URL)” ##### THIS is the VALUE i need to export to CSV as well
foreach($list in $Web.Lists)
{
#Filter Doc Libs, Eliminate Hidden ones
if(($List.BaseType -eq “DocumentLibrary”) -and ($List.Hidden -eq $false) )
{
Get-SPFiles($List.RootFolder) | Export-Csv -Path d:\wo\abc.csv -NoTypeInformation -Append ### Only exports $file.name and $file.URL
}
}
} [/pre]

Try something like this:

#Get the Site collection
$Site= Get-SPSite 'https://dev.mycompany.com/sites/Stuff'
#all results returned roll up to the $results variable
$results = foreach($Web in $Site.AllWebs) {
 
    #Get all of the files from the function and put them in the $files variable
    $files = foreach($list in $Web.Lists){
        #Filter Doc Libs, Eliminate Hidden ones
        if(($List.BaseType -eq 'DocumentLibrary') -and ($List.Hidden -eq $false) )    {
            GetFiles($List.RootFolder)
        }
    }

    #Use a calculated expression to append web items to the files.
    $files | Select *,
                    @{Name='Title';Expression={$web.Title}},
                    @{Name='Url';Expression={$web.Url}}
    
}

Thanks Rob! piping out the $results gives me all 3 values we needed. Much appreciated sir.