Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't pipe Azcontext object in azure function environment to output/log #306

Open
bingbing8 opened this issue Aug 7, 2019 · 4 comments
Open
Assignees
Milestone

Comments

@bingbing8
Copy link

bingbing8 commented Aug 7, 2019

I have below azure ps function. Looks like the object returned to caller, but the returned object can't pipe to log. Is this intended?
if run the script not in ps function environment, the caller can receive the object can pipe the return to output

using namespace System.Net
using namespace Microsoft.Azure.Functions.PowerShellWorker
param($Request, $TriggerMetadata)
Write-Host "PowerShell http trigger function processed work item"
function Install-Certificate
{
    param(
        [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,
        [string]$StorePath
    )
    Write-Host "Install-Certificate"
    $store = Get-Item $storePath -ErrorAction Stop
    try
    {
        $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
    }
    catch
    {
        throw "Failed to open cert store {0} -- {1}" -f $storePath,$a
    }
    try
    {
        $store.add($Certificate)
    }
    catch
    {
        throw "Failed to add certificate to cert store {0} -- {1}" -f $storePath,$a
    }
    $store.close()
    Write-Host "End of Install-Certificate"
}

function Connect-CustomerTenant1
{
    param(
        [Parameter(Mandatory=$true)][string]$SubscriptionId,
        [Parameter(Mandatory=$true)][string]$SPNId,
        [Parameter(Mandatory=$true)][string]$KeyVaultName,
        [string]$TenantId = "72f988bf-86f1-41af-91ab-2d7cd011db47",        
        [string]$AzureEnvironmentName = "AzureCloud"
    )

    $cnt = 0
    $MaximumRetryCount = 3

    $ctx = Connect-AzAccount -Identity -Force
    $kvSecret = Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name $SPNId -DefaultProfile $ctx
    $kvSecretBytes = [System.Convert]::FromBase64String($kvSecret.SecretValueText)
    $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($kvSecretBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet)

    $thumbprint = $certificate.Thumbprint
    Write-Host "Thumbprint: $thumbprint"
    Install-Certificate -Certificate $certificate -StorePath "Cert:\CurrentUser\My"
    do {
        $cnt++
        $exceptionMessage = $null
        try {
                Write-Host "Connect-AzAccount..."
                $Script:AzContext = Connect-AzAccount -CertificateThumbprint $thumbprint `
                                                    -ApplicationId $SPNID -Tenant $TenantID `
                                                    -ServicePrincipal -Environment $AzureEnvironmentName `
                                                    -SubscriptionId $SubscriptionId -ErrorAction Stop
                Write-Host "After Connect-AzAccount ..."
                # validate due to bug in az module (bug link: https://github.com/Azure/azure-powershell/issues/9448)
                $rglist = Get-AzResourceGroup -DefaultProfile $Script:AzContext
                Write-Host "Get $($rglist.Count) resource groups"
                Write-Host "After validation ..."
                Write-Host "Execution count: $cnt"
                Write-Host "context: $($Script:AzContext | Out-String)"
                #return
                # bug: the axContext does not return to caller
                return $Script:AzContext
            }
            catch 
            {
                Write-Host "AzContext in exception: $(Get-AzContext | Out-String)"
                Write-Host "Connect-AzAccount failed, retry count: $cnt"
                $exceptionMessage = $_.Exception.Message
                Write-Host $exceptionMessage
                if($_.Exception.InnerException)
                {
                    Write-Host $_.Exception.InnerException.Message
                    #$exceptionMessage += $_.Exception.InnerException.Message 
                }
            }
    } while ($cnt -lt $MaximumRetryCount)

    # Throw an error after $MaximumRetryCount unsuccessful invocations. Doesn't need
    # a condition, since the function returns upon successful invocation.
    Write-Host "connect-Azacccount failed. retry count: $cnt"
    throw "Login validation failed. $exceptionMessage"
}

   try
    {
        $cxt = Connect-CustomerTenant1 -SubscriptionId "e9c08608-0c4f-4a51-8640-968eafc186af" `
                -TenantId "72f988bf-86f1-41af-91ab-2d7cd011db47" `
                -SPNID "70402f7e-6079-44ef-865f-55315dc7ce19" `
                -KeyVaultName "amvmyawang-kv"
        if($cxt)
        {
            $body = $cxt | out-string
            #Write-Output "body:"
            #Write-Output $body
            #Write-Output "Type of cxt: $($cxt.GetType())"
            Write-Output "returned cxt in caller:"
            Write-output $cxt
            Write-Host "context:"
            Write-Output $cxt.Context
            Write-Host "context | Out-String"
            Write-Output $($cxt.Context | fl * | Out-String)
            #Write-Output $($cxt.Context | Get-Member)
            Write-Host "Hello"

            #$rglist = Get-AzResourceGroup -DefaultProfile $cxt
            #Write-Output $rglist
        }
        else {
            Write-Host "cxt is null in caller"
        }
    }
    catch
    {
        Write-Host $_.Exception.Message
    }
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = [HttpStatusCode]::OK
        Body = $body
    })

output in ps azure function:
2019-08-08T20:30:03.599 [Information] Executing 'Functions.bugrepro' (Reason='This function was programmatically called via the host APIs.', Id=a170dcbe-6062-420f-afc7-907d52a1081c)
2019-08-08T20:30:14.138 [Information] INFORMATION: PowerShell http trigger function processed work item
2019-08-08T20:30:21.155 [Information] INFORMATION: Thumbprint: E03A6AD85BEF21B872C1075EF3B6E5749904F232
2019-08-08T20:30:21.156 [Information] INFORMATION: Install-Certificate
2019-08-08T20:30:21.234 [Information] INFORMATION: End of Install-Certificate
2019-08-08T20:30:21.234 [Information] INFORMATION: Connect-AzAccount...
2019-08-08T20:30:21.993 [Information] INFORMATION: After Connect-AzAccount ...
2019-08-08T20:30:27.473 [Information] INFORMATION: Get 3 resource groups
2019-08-08T20:30:27.476 [Information] INFORMATION: After validation ...
2019-08-08T20:30:27.476 [Information] INFORMATION: Execution count: 1
2019-08-08T20:30:27.477 [Information] INFORMATION: context:
Account SubscriptionName TenantId Environment


70402f7e-6079-44ef-865f-55315dc7ce19 TestEA Customer3 72f988bf-86f1-41af-91ab-2d7cd011db47 AzureCloud
2019-08-08T20:30:27.477 [Information] OUTPUT: returned cxt in caller:
2019-08-08T20:30:27.477 [Information] OUTPUT:
2019-08-08T20:30:27.478 [Information] INFORMATION: context:
2019-08-08T20:30:27.478 [Information] INFORMATION: context | Out-String
2019-08-08T20:30:27.478 [Information] INFORMATION: Hello
2019-08-08T20:30:29.490 [Information] Executed 'Functions.bugrepro' (Succeeded, Id=a170dcbe-6062-420f-afc7-907d52a1081c)

@bingbing8 bingbing8 changed the title Azcontext object does not returned to caller azure function Azcontext object does not return to caller azure function Aug 7, 2019
@bingbing8 bingbing8 changed the title Azcontext object does not return to caller azure function Can't pipe Azcontext object returned to caller azure function to output Aug 7, 2019
@JustinGrote
Copy link

JustinGrote commented Aug 7, 2019 via email

@bingbing8
Copy link
Author

bingbing8 commented Aug 7, 2019

@JustinGrote, log is what I want. the issue is the object can't pipe to log. I pipe it to log for troubleshooting purpose, It always output empty, which cost me long time to figure out this object is not null, but just not able to pipe to log

@bingbing8 bingbing8 changed the title Can't pipe Azcontext object returned to caller azure function to output Can't pipe Azcontext object returned to caller azure function to output/log Aug 7, 2019
@JustinGrote
Copy link

Did you try piping it to format-list -prop * | out-string? It may have a default tostring of null or something.

Maybe also try.gettype() on it

@bingbing8
Copy link
Author

bingbing8 commented Aug 8, 2019

@JustinGrote , if in the my code, here is find out:

  1. Write-host $($cxt | out-string) logs fine
  2. Write-Output "Type of cxt: $($cxt.GetType())" logs fine
  3. Write-Output $($cxt.Context | Get-Member) logs fine
  4. Write-Output $cxt does not log
  5. Write-Output $cxt.Context does not log
  6. Write-Output $($cxt.Context | fl * | Out-String) does not log
  7. Write-Host "$($cxt.Context | fl * | Out-String)" logs fine
  8. if the same script run in normal powershell prompt (not in ps function), write-output print out $cxt

Why does it like this?

@bingbing8 bingbing8 changed the title Can't pipe Azcontext object returned to caller azure function to output/log Can't pipe Azcontext object in azure function environment to output/log Aug 8, 2019
@eamonoreilly eamonoreilly added this to the Investigating milestone Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants