0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ServiceNowの問題チケットに添付ファイルを移行する方法

Last updated at Posted at 2025-04-15

✅ 前提整理

項目 内容
添付対象 problem テーブル
各フォルダ名 特定のキーワード(例:PRB0012345や「network」など)
→ これをServiceNow APIで検索キーに使う
ファイル構造 例:C:\UploadRoot\PRB0012345\file1.pdfC:\UploadRoot\network\log.txt
使用API GET /api/now/table/problem?sysparm_query=... でレコード検索 → POST /attachment/file で添付

🐋 PowerShellスクリプト案(キーワード→sys_id取得→添付)

# 認証・インスタンス設定
$Username = "your_username"
$Password = "your_password"
$Base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$Username:$Password"))
$Instance = "your_instance.service-now.com"
$TableName = "problem"

# ルートディレクトリ(フォルダ名=キーワード)
$RootFolder = "C:\UploadRoot"

# プロキシ対応クライアント
$Handler = New-Object System.Net.Http.HttpClientHandler
$Handler.UseProxy = $true
$Handler.Proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$Handler.Proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials

$Client = New-Object System.Net.Http.HttpClient($Handler)
$Client.DefaultRequestHeaders.Authorization = [System.Net.Http.Headers.AuthenticationHeaderValue]::new("Basic", $Base64AuthInfo)
$Client.DefaultRequestHeaders.Accept.Add([System.Net.Http.Headers.MediaTypeWithQualityHeaderValue]::Parse("application/json"))

# フォルダごとに処理
Get-ChildItem -Path $RootFolder -Directory | ForEach-Object {
    $Keyword = $_.Name
    $FolderPath = $_.FullName

    # 🔍 キーワードでレコード検索(例では「number」フィールドと一致)
    $Query = "number=$Keyword"  # 例: PRB0012345と一致
    $SearchUrl = "https://$Instance/api/now/table/$TableName?sysparm_query=$Query&sysparm_limit=1"
    $SearchResult = $Client.GetAsync($SearchUrl).Result
    $JsonResult = $SearchResult.Content.ReadAsStringAsync().Result | ConvertFrom-Json

    if ($JsonResult.result.Count -eq 0) {
        Write-Host "⚠ レコードが見つかりません: $Keyword"
        return
    }

    $RecordSysId = $JsonResult.result[0].sys_id
    Write-Host "`n📁 [$Keyword] → sys_id: $RecordSysId"

    # ファイルごとに添付
    Get-ChildItem -Path $FolderPath -File | ForEach-Object {
        $FilePath = $_.FullName
        $FileName = $_.Name

        $Url = "https://$Instance/api/now/attachment/file?table_name=$TableName&table_sys_id=$RecordSysId&file_name=$FileName"

        $FileBytes = [System.IO.File]::ReadAllBytes($FilePath)
        $FileContent = New-Object System.Net.Http.ByteArrayContent($FileBytes)
        $FileContent.Headers.ContentDisposition = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
        $FileContent.Headers.ContentDisposition.Name = '"file"'
        $FileContent.Headers.ContentDisposition.FileName = '"' + $FileName + '"'
        $FileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/octet-stream")

        $Multipart = New-Object System.Net.Http.MultipartFormDataContent
        $Multipart.Add($FileContent)

        $Response = $Client.PostAsync($Url, $Multipart).Result

        if ($Response.IsSuccessStatusCode) {
            Write-Host "✅ $FileName を添付しました"
        } else {
            Write-Host "❌ $FileName の添付失敗"
            $Response.Content.ReadAsStringAsync().Result
        }
    }
}

✅ カスタマイズ例

目的 方法
タイトルで部分一致検索 $Query = "short_descriptionLIKE$Keyword"
番号で前方一致検索 $Query = "numberSTARTSWITH$Keyword"
キーワードをファイル名から抽出したい Split-Path $FilePath -LeafBase などで処理可
レコードが複数一致する場合の処理 $JsonResult.result[0] をループに変えることで対応可

🧪 テストのおすすめ手順

  1. 1件のフォルダで動作確認(例:C:\UploadRoot\PRB0012345
  2. ServiceNowで該当レコードを開き、添付ファイルが正しく表示されているか確認
  3. 問題なければ複数フォルダへ展開

必要であれば、

  • キーワードをCSVから読み取る形式
  • 添付のログ出力保存
    なども対応できます。必要な方向性があればぜひ教えてください!
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?