【AzureAutomation PowerShell】SQLServerクエリ結果をCSVファイル（項目ごとのダブルクォートなし、エンコードUTF-8、BOM無し）に保存する

##全部記載されている記事が無いように思えたので纏めてみました

全体のコードは以下のとおり

```
param(

        [parameter(Mandatory=$True)]
        [string] $SqlServer,

        [parameter(Mandatory=$True)]
        [int] $SqlServerPort,

        [parameter(Mandatory=$True)]
        [string] $Database,

        [parameter(Mandatory=$True)]
        [string] $Table,

        [parameter(Mandatory=$True)]
        [PSCredential] $SqlCredName,

        [parameter(Mandatory=$True)]
        [string] $resourceGroup,

        [parameter(Mandatory=$True)]
        [string] $storageAccountName,

        [parameter(Mandatory=$True)]
        [string] $ContainerName

    )

    $dt = Get-Date
    $FileName = $dt.ToString("_yyyy-MM-dd HH:mm:ss.fff") + ".csv"
    $LocalFile = "C:\test.csv"

    $Conn = Get-AutomationConnection -Name AzureRunAsConnection
    $Null = Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
    $Null = Set-AzureRmCurrentStorageAccount -ResourceGroupName $resourceGroup -StorageAccountName $storageAccountName

    # Get the username and password from the SQL Credential
    $SqlUsername = $SqlCredName.UserName
    $SqlPass = $SqlCredName.GetNetworkCredential().Password

    # Define the connection to the SQL Database
   $Conn = New-Object System.Data.SqlClient.SqlConnection("Server=tcp:$SqlServer,$SqlServerPort;Database=$Database;User ID=$SqlUsername;Password=$SqlPass;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;")

    # Open the SQL connection
    $Conn.Open()

 
    # Define the SQL command to run. In this case we are getting the number of rows in the table
    $Cmd=new-object system.Data.SqlClient.SqlCommand("SELECT ID, CONVERT(VARCHAR, TimeStamp, 127) as DateTime, Message ,RawMessage from [dbo].[$Table]", $Conn)
    $Cmd.CommandTimeout=120

    # DataTableを利用してSQL実行結果を一時格納
    [System.Data.DataTable]$resultsDataTable = New-Object System.Data.DataTable;
    # ExecuteReaderを実行してDataTableにデータを格納
    [object]$resultsDataTable.Load($Cmd.ExecuteReader());

    if ([int]$resultsDataTable.rows.count -gt 0){
        #######################################################
        #### ヘッダの生成
        $Header = ""
        foreach ($Column in $resultsDataTable.Columns)
        { 
      
            if ($Column.ColumnName -eq "RawMessage"){
                $Header += "$Column`r`n"

            }else{
                $Header += "$Column,"

            }   

        }

        #### 本体の生成
        $Body = ""
        foreach ($Row in $resultsDataTable.Rows)
        { 

            foreach ($Column in $resultsDataTable.Columns)
            { 
        
                if ($Column.ColumnName -eq "RawMessage"){
                    $Body += "$($Row[$Column.ColumnName])`r`n"

                }else{
                    $Body += "$($Row[$Column.ColumnName]),"

                }   

            }

        }

        $ExportValue = $Header + $Body

        # CSV形式で標準出力
        ###-UseQuotes オプションはpowershell ver7以降から実装される（将来用にここに残す）
        #$resultsDataTable | Export-Csv $LocalFile -Encoding UTF8 -UseQuotes Never
        #$resultsDataTable | Export-Csv $LocalFile -Encoding UTF8 -NoTypeInformation
        $ExportValue | Out-File $LocalFile -Encoding UTF8

        #######################################################

        $CurrentContesnt = Get-Content $LocalFile
        $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
        [System.IO.File]::WriteAllLines($LocalFile, $CurrentContesnt, $Utf8NoBomEncoding)

        # Upload file to the Blob Storage
        Set-AzureStorageBlobContent -File $LocalFile -Container $ContainerName -Blob $FileName

    }else{
        Write-Output "EORを検出しました。"
        break

    }

    # Close the SQL connection
    $Conn.Close()



```

次の部分でダブルクォートを取り除いています。

```

        #### ヘッダの生成
        $Header = ""
        foreach ($Column in $resultsDataTable.Columns)
        { 
      
            if ($Column.ColumnName -eq "RawMessage"){
                $Header += "$Column`r`n"

            }else{
                $Header += "$Column,"

            }   

        }

        #### 本体の生成
        $Body = ""
        foreach ($Row in $resultsDataTable.Rows)
        { 

            foreach ($Column in $resultsDataTable.Columns)
            { 
        
                if ($Column.ColumnName -eq "RawMessage"){
                    $Body += "$($Row[$Column.ColumnName])`r`n"

                }else{
                    $Body += "$($Row[$Column.ColumnName]),"

                }   

            }

        }

        $ExportValue = $Header + $Body

        # CSV形式で標準出力
        $ExportValue | Out-File $LocalFile -Encoding UTF8

```

ダブルクォートを取り除く部分ですが、PowerShell 7 以降は次の１文で解決出来てしまいそうです。

```

        $resultsDataTable | Export-Csv $LocalFile -Encoding UTF8 -NoTypeInformation -UseQuotes Never

```

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/export-csv?view=powershell-7.1

現時点のAzureAutomationで使用できるPowerShellのversionは次のとおり。

```

#RunBookのPowerShell内で次のコマンドを実行
Write-Output $PSVersionTable

#(結果)
Name                           Value                                                                                    
----                           -----                                                                                    
PSVersion                      5.1.17134.1792                                                                           
PSEdition                      Desktop                                                                                  
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                  
BuildVersion                   10.0.17134.1792                                                                          
CLRVersion                     4.0.30319.42000                                                                          
WSManStackVersion              3.0                                                                                      
PSRemotingProtocolVersion      2.3                                                                                      
SerializationVersion           1.1.0.1        

```

次の部分で、エンコードUTF8で仮保存しています。

```

        $ExportValue | Out-File $LocalFile -Encoding UTF8


```

次の部分で、仮保存したファイルの内容をBOM無し保存しています。

```

        $CurrentContesnt = Get-Content $LocalFile
        $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
        [System.IO.File]::WriteAllLines($LocalFile, $CurrentContesnt, $Utf8NoBomEncoding)

```

もうすこし後の仕事だったら AzureAutomation PowerShell version7 がリリースされていたかもです...。:sweat:

https://azure.microsoft.com/ja-jp/updates/powershell-7-azure-automation-coming-soon/