เชื่อมต่อ SQL Server database ด้วย PowerShell และอ่านรหัสผ่านจาก text file

enter image description here

ใน PowerShell เราสามารถใช้ Invoke-Sqlcmd Cmdlet (Cmdlet เป็นการเรียก function ใน PowerShell อ่านว่า command let) เพื่อทำการ query หรือ manipulate ข้อมูลใน database

โดยทั่วไป เราก็มักจะใช้ในรูปแบบที่ส่ง username และ password เข้าไปตรงๆ สำหรับ SQL Server authentication login ตัวอย่างเช่น การ query ข้อมูลทุก records ใน table users

Invoke-Sqlcmd -ServerInstance "localhost" -Database "codesanook" -Username "sa" -Password "MyStrongPassword" -Query "select * from users"

แต่หากเราต้องการที่จะเขียนคำสั่ง PowerShell นี้เป็น script โดยให้ทำงานในลักษณะ cron job, task scheduler เราควรทำการเข้ารหัส password ไว้ และที่คำสั่ง Invoke-Sqlcmd จะมี parameter ที่ชื่อว่า Credential ที่ให้เราสามารถส่งค่า PSCredential object เข้าไปได้ โดยเราสามารถสร้าง object จาก encrypted password ที่เก็บไว้ใน file ได้

ในตัวอย่างนี้ เราจะสร้าง PowerShell Module (.psm1) ง่ายๆ โดยมี 3 functions หลักดังนี้

  • Save-SecurePasswordToFile ทำการแปลง plain text password เป็น secure string, encrypt secure password และ save ลง text file
  • Get-SecurePasswordFromFile ทำการ encrypt password ที่อยู่ใน text file ขึ้นมาเป็น secure string
  • Get-CredentialFromFile สร้าง System.Management.Automation.PSCredential object จาก encrypted password file โดยตัวมันเองจะไปเรียกใช้ Get-SecurePasswordFromFile อีกทีนึง

ตัวอย่าง code ของ script SecurePasswordFile.psm1

<#
.SYNOPSIS
    To use functions in this modules, call Import-Module -Name .\SecurePasswordFile -Verbose
#>

function Save-SecurePasswordToFile {
    param(
        [Parameter(Mandatory = $true)] [SecureString] $Password,
        [Parameter(Mandatory = $true)] [string] $EncryptedFilePath
    )

    ConvertFrom-SecureString -SecureString $Password | Out-File -FilePath $EncryptedFilePath
}

function Get-SecurePasswordFromFile {
    param(
        [Parameter(Mandatory = $true)] [string] $EncryptedFilePath
    )

    Get-Content -Path $EncryptedFilePath | ConvertTo-SecureString
}

function Get-CredentialFromFile {
    param(
        [Parameter(Mandatory = $true)] [string] $Username,
        [Parameter(Mandatory = $true)] [string] $EncryptedFilePath
    )

    $securePassword = Get-SecurePasswordFromFile -EncryptedFilePath $EncryptedFilePath
    New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($Username, $securePassword)
}

Export-ModuleMember Save-SecurePasswordToFile
Export-ModuleMember Get-SecurePasswordFromFile
Export-ModuleMember Get-CredentialFromFile

ตัวอย่างการใช้งาน

เริ่มจาก import SecurePasswordFile module ขึ้นมากก่อน

> Import-Module -Name .\SecurePasswordFile -Verbose

เรียกใช้งาน Save-SecurePasswordToFile Cmdlet

> Save-SecurePasswordToFile

รอสักครู่ แล้วกรอก plain text plain และ path ของ file ที่ต้องการ save encrypted password

cmdlet Save-SecurePasswordToFile at command pipeline position 1
Supply values for the following parameters:
Password: *****
EncryptedFilePath: password.txt

จากนั้นก็เรียกใช้ Get-CredentialFromFile โดยการเก็บ output เข้าไปในตัวแปร $cred

> $cred = Get-CredentialFromFile -Username sa -EncryptedFilePath password.txt

เราก็จะได้ตัวแปรก $cred ที่มี username และ password เพื่อไปใช้ใน Invoke-Sqlcmd ได้แล้วครับ ตัวอย่างการใช้งาน

> Invoke-Sqlcmd -ServerInstance "localhost" -Database "codesanook" -Credential $cred  -Query "select * from users"

ขอบคุณครับ