Home > Mobile >  PowerShell - How to pass an array by ref
PowerShell - How to pass an array by ref

Time:12-25

As below you can see that if files are not located at $FilesPath I try to search in $fallbackpath. The problem is that after I call to fallback the $compressedfiles is empty. maybe the ref for array is not right?

Function Init {
    $compressedfiles = @()
    $compressedfiles = Get-ChildItem -path $FilesPath\* -Include "*.vip", "*.zip", "*.cab"
    if (-Not $compressedfiles) {
        fallback
    }
}

Function fallback {
    $fallbackpath = '\\google.com\global\builds\PatchCreatorOutput'
    $compressedfiles = Get-ChildItem -path $fallbackpath\$FolderNumber\* -Include "*.vip", "*.zip", "*.cab"
    ([ref]$compressedfiles).Value = $compressedfiles
}

Update: In order to see the files from $compressedfiles after fallback I changed to this: (added return and global for the Init function)

Function Init {
        $compressedfiles = @()
        $compressedfiles = Get-ChildItem -path $FilesPath\* -Include "*.vip", "*.zip", "*.cab"
        if (-Not $compressedfiles) {
            fallback
        }


Set-Variable -Name "compressedfiles" -Value $compressedfiles -Scope global
    }
    
    Function fallback {
        $fallbackpath = '\\google.com\global\builds\PatchCreatorOutput'
        $compressedfiles = Get-ChildItem -path $fallbackpath\$FolderNumber\* -Include "*.vip", "*.zip", "*.cab"
        return $compressedfiles | out-null
    }

CodePudding user response:

Continuing from my comment, you need to use Scoping to reference variables declared outside the functions in order to manipulate them.

Without scoping, these variables are simply new, local variables that exist in the function only.

Why not try

function Init {
    $script:compressedfiles = Get-ChildItem -Path $script:FilesPath -Recurse -Include "*.vip", "*.zip", "*.cab"
    if (-Not $script:compressedfiles) {
        $script:compressedfiles = fallback
    }
}

function fallback {
    $fallbackpath = '\\google.com\global\builds\PatchCreatorOutput'
    # just output
    Get-ChildItem -Path "$fallbackpath\$script:FolderNumber" -Recurse -Include "*.vip", "*.zip", "*.cab"
}

# Main script

# declare the variables you want the functions to see/manipulate here
# inside the functions you reference them with '$script:variablename'
$compressedfiles = $null  # declared outside the functions
$FilesPath       = '\\google.com\global\builds\SomeWhereToStartWith'
$FolderNumber    = 1
# call Init
Init
# show what $compressedfiles contains
$compressedfiles | Format-Table -AutoSize

CodePudding user response:

([ref]$Item).Value changes the item of the closest parent that created it

Note that the Init function itself, is a child of the PowerShell prompt. meaning if you want to check the results of the $compressedfiles in the Init function scope you will need to output that. If you want to check the $compressedfiles at the prompt you probably want to use the global scope as answered by @Santiago Squarzon in you previous question about global variables.

Also note that the child fallback function should be defined prior the parent init function that uses it.

Function fallback {
    ([ref]$compressedfiles).Value = @('file3', 'file4')
}

Function Init ([switch]$CheckEmpty) {
    $compressedfiles = if (!$CheckEmpty) { @('file1', 'file2') }
    if (-Not $compressedfiles) {
        fallback
    }
    $compressedfiles # <-- output the value in the init scope
}
Init
file1
file2
Init -CheckEmpty
file3
file4
  • Related