azurepowershellautomationfilesharerunbook

Not able to access Azure FileShare Storage container from Azure Automation Runbook


I've the following Azure Automation Runbook script which goal is to take an dump/export from a REST API call which must run from a target device which is able to reach the REST API device. So Azure Automation runbook is targeting a "proxy server" then from this we're taking the REST API backup.

The approach has been working exception the fact we're able not to copy this backup file from the target server once 'cm.vm.run_command' presents output size limitation and is truncating the backup. The workaround we found for this was copying the backup file from the 'target/proxy server' directly into a Storage Account Fileshare which is mounted on the target/proxy server. My problem now is when running from Azure Automation it's not able to access the drive mounted by other user and/or is not able to mount the device or access it directly like below errors messages. Does anybody have any alternative for this ? I was able to check the runbook is having connectivity on the storage account ports 443/445 from t. That was one of the possible reasons described here https://learn.microsoft.com/en-us/azure/storage/files/storage-troubleshoot-windows-file-connection-problems

Below the commands and errors I'm receiving and the whole script used.

Copy-item -Path C:\Devicebackup.txt -Destination \\storage_account_name.file.core.windows.net\configdatafileshare\Orchestration 
net use w: \\storage_account_name.file.core.windows.net\configdatafileshare\Orchestration `'/yBapkthow==`' /user:Azure\storage_account_name

Copy-item : The network path was not found
At C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.5\Downloads\s
cript9.ps1:15 char:1
+ Copy-item -Path C:\Devicebackup.txt -Destination \\storage_account_name. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Copy-Item], IOException
    + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Comma 
   nds.CopyItemCommand
 
The option /DL2D2QKD1OU2ZKEOJVRK4LGPIRTJKAJBZ+EDKNHWVYYEJDDYSL9CPB5T8F/9VWQBMBWC37B1NJS4YBAPKTHOW== is unknown.

The syntax of this command is:

NET USE
[devicename | *] [\\computername\sharename[\volume] [password | *]]
        [/USER:[domainname\]username]
        [/USER:[dotted domain name\]username]
        [/USER:[username@dotted domain name]
        [/SMARTCARD]
        [/SAVECRED]
        [[/DELETE] | [/PERSISTENT:{YES | NO}]]

NET USE {devicename | *} [password | *] /HOME

NET USE [/PERSISTENT:{YES | NO}]
Param (
    [Parameter(Mandatory=$false)][string] $rgName
    ,[Parameter(Mandatory=$false)][string] $ProxyServerName
)


function CreatePSCommandFile {
    Param(
    [parameter(Mandatory=$true)][String[]]$DeviceName,
    [parameter(Mandatory=$true)][String[]]$DeviceIP,
    [parameter(Mandatory=$true)][String[]]$ApiToken   
    )

    $remoteCommand =
@"
add-type @`"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
`"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri 'www.mydownload.com' -UseBasicParsing -Headers @{    Authorization="Bearer $($ApiToken)" } | Out-file C:\Devicebackup.txt
net use w: \\storage_account_name.file.core.windows.net\configdatafileshare\Orchestration `'/STORAGE_KEY+EDknHWvyyeJDDYsL9cPB5T8F/9VwqBmbwc37B1NJS4yBapkthow==`' /user:Azure\storage_account_name
Copy-item -Path C:\Devicebackup.txt -Destination \\storage_account_name.file.core.windows.net\configdatafileshare\Orchestration

"@
    Set-Content -Path .\InvokeCommand.ps1 -Value $remoteCommand
}
$connectionName = "AzureRunAsConnection"
try {
    # Get the connection "AzureRunAsConnection "
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName         
    Write-Host "Logging in to Azure..."
    $connectionResult = Connect-AzAccount `
        -ServicePrincipal `
        -Tenant $servicePrincipalConnection.TenantID `
        -ApplicationId $servicePrincipalConnection.ApplicationID `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
    if (!$servicePrincipalConnection)
    {
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    } else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}


function Backup-Device {
    Param (
        [Parameter(Mandatory=$false)][string] $DeviceName
        ,[Parameter(Mandatory=$false)][string] $DeviceIP
        ,[Parameter(Mandatory=$false)][string] $ApiToken        
    )
    # Execute Backup on Fortigate Rest API
    CreatePSCommandFile -DeviceName $DeviceName -DeviceIP $DeviceIP -ApiToken $ApiToken
    $Output = Invoke-AzVMRunCommand -ResourceGroupName $rgName -VMName $ProxyServerName -CommandId 'RunPowerShellScript' -Scriptpath ".\InvokeCommand.ps1"  -Parameter @{'api_url' = "10.29.255.212"; 'api_token' = "0p6h1rmspjf37kp80bc6ny88jw"}
    ($Output).Value.Message
}

Backup-Device -DeviceName "DeviceName" -DeviceIP '10.29.255.212' -ApiToken 'Api_Token'

Solution

  • Sharing the solution which was presented by a blessed colleague :)

    Using New-SmbMapping we were able to mount the Storage Account File Share from Azure Automation PS script successfully.

    if (!(Test-Path `$MapDrive)) {
        New-SmbMapping -LocalPath `$MapDrive -RemotePath `$RemotePath -UserName `$UserName -Password `$Key
    }
    Copy-Item .\Devicebackup.txt `$MapDrive