0

I am looking to pass a bunch of variables to the parameters of a function but since the script needs to be run unattended I will need to pass these variables within the script. i.e via invoke-expression or otherwise.

Below is the functions I am using:

Function Get-AzStorageContainerSASUri {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        $TenantId,
        
        [Parameter(Mandatory)]
        [String]$SubscriptionId,

        [Parameter(Mandatory)]
        [String]$ResourceGroupName,

        [Parameter(Mandatory)]
        [String]$StorageAccountName,

        [Parameter(Mandatory)]
        [String]$ContainerName,

        [Parameter(Mandatory=$false)]
        [Int]$TokenDurationMinutes = 15,

        [Parameter(Mandatory)]
        [System.Management.Automation.PSCredential]$Credential
    )
        
        # Connect as Service Principal
        Connect-AzAccount -TenantId $TenantId -Credential $Credential -ServicePrincipal -WarningAction 'SilentlyContinue' | Out-Null
        Select-AzSubscription -SubscriptionId $SubscriptionId | Out-Null
    
        # Load the Storage Account context
        $StorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $ResourceGroupName -AccountName $StorageAccountName)[0].Value
        $StorageContext    = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
    
        # Generate a full URI to the container with SAS token
        $SasParam = @{
            Context    = $StorageContext
            Name       = $ContainerName
            ExpiryTime = (Get-Date).AddMinutes($TokenDurationMinutes)
            Permission = 'rw'
            FullUri    = $true
        }
        
        $DestinationUri = New-AzStorageContainerSASToken @SasParam
        Return $DestinationUri
    }

And here is the main script where I have put an invoke expression to assign the values to the parameters.

Foreach ($Source in $Sources) {
     $Destination = Get-AzStorageContainerSASUri | Invoke-Expression '[string]$TenantId = "xxxxx-xxxxxx-xxxxx"', '[string]$SubscriptionId = "xxxxxxx-xxxxxx-xxxx"', '[string]$ResourceGroupName = "xxxxxx-xxxxx-xxxxx"', '[string]$StorageAccountName = "woukasrtest211202"', '[string]$Credential = Import-Clixml -Path "C:\AzCopy\xxxxxx-xxxxxxx-xxxxxx.credential"'
    Sync-SftpToAzStorage -Source $Source -Destination $Destination ...
} 

This should theoretically use both functions I've written without me needing to input for the parameters in the first function. However, I either get the error: "Expressions are only allowed as the first element of a pipeline." OR the invoke-expression doesn't seem to run at all and I get:"cmdlet Get-AzStorageContainerSASUri at command pipeline position 1 Supply values for the following parameters: TenantId:"

I believe its invoke-expression or invoke-command but I can't seem to get it working the way that is perhaps intended to achieve my desired outcome.

Thanks, Evan

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • `Invoke-Expression` (`iex`) should generally be _avoided_ and used only as a _last resort_, due to its inherent security risks. Superior alternatives are usually available. If there truly is no alternative, only ever use it on input you either provided yourself or fully trust - see [this answer](https://stackoverflow.com/a/51252636/45375). – mklement0 Jan 29 '22 at 02:23
  • 1
    If your intent is to programmatically construct arguments for a call to your `Get-AzStorageContainerSASUri` function, consider the use of [splatting](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Splatting). – mklement0 Jan 29 '22 at 02:26
  • 1
    THanks mlement0 I will check both out. – Evan Thomas-Broughton Jan 29 '22 at 10:45

1 Answers1

0

In the end this was solved by listing them out after the function call to pass the variable to the functions parameters:

Foreach ($Source in $Sources) {
 $Destination = Get-AzStorageContainerSASUri -TenantId $TenantId -SubscriptionId $SubscriptionId -ResourceGroupName $ResourceGroupName -StorageAccountName $StorageAccountName -Credential $Credential
Sync-SftpToAzStorage -Source $Source -Destination $Destination ...

}

  • For readability and ease of maintenance, you should use splatting when passing a lot of arguments to a cmdlet. See [about_Splatting](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting). – Damian T. Jan 31 '22 at 23:42