プリザンターでPC資産管理システムを構築する

# はじめに
プリザンターでPC資産管理ツールみたいなものを作れるのでは、と思い作ってみました。
※ windowsPC限定の内容です。

### プリザンターで連携するPC情報
とりあえず、これらの項目があれば十分かな、という想定。
| # |  名称                             |
|---|----------------------------------|
| 1 | コンピュータ名                   |
| 2 | IPアドレス                       |
| 3 | OS                               |
| 4 | インストール済みアプリケーション |

# 環境イメージ
社内環境に複数PCがあり、OSやPC名などの情報をタスクスケジューラーで定期的に送信する事を想定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/63f2e17e-ef6c-4e41-d2ab-72e01555e430.png)

# プリザンターの設定
[新規作成] → [記録テーブル] → [作成]を選択し、「PC管理」テーブルを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/6c7a99e5-66e0-ff82-8548-bd6155f55afe.png)

作成したPC管理を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/c50ed5a8-18cf-d49f-45e0-d0fcf64b1c37.png)

[管理] → [テーブルの管理]を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/321692f0-8471-0c18-1c64-f3a3cdfcb01a.png)

エディタタブから設定を以下の様にします。

| # | 項目  | 名称                             |
|---|-------|----------------------------------|
| 1 | ID    | ID                               |
| 2 | 説明A | コンピュータ名                   |
| 3 | 説明B | IPアドレス                       |
| 4 | 説明C | OS                               |
| 5 | 説明D | インストール済みアプリケーション |

作成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/3c5fb5a0-1db7-cf59-6ede-cebaf1d84ddb.png)

# データ収集プログラムの作成
visual studio 2022を起動し、コンソールアプリケーションを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/5ac8fbd8-2f8d-f500-bbea-e9bcbba3ccd8.png)
名称は「ConsoleApp1」で「.NET 8.0」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/8a17f4f6-0f36-909f-6cb3-ae3e1e7b4899.png)

### データ収集プログラム
折角ローコードツールを使っているので、プログラム部分もなんとかできないかと思い、AIに相談してコードを書いてもらいました。
やはり一発で思った感じのプログラムを生成する事は難しく、部分毎にお願いし結果を手動で組み合わせるという手法を取っています。

#### プログラム補足事項
実行毎に同じデータが複数登録されると困るので、コンピュータ名が同じレコードにある場合はレコードを更新、一致するレコードがない場合は新規作成するといった形にしています。この仕組みはプリザンターの[レコード作成・更新](https://pleasanter.org/manual/api-record-upsert)機能で実現しています。


```cs
using Microsoft.Win32;
using System.Net;
using System.Net.Sockets;
using System.Management;
using System.Text;
using System.Text.Json;

class Program
{
    static readonly HttpClient client = new HttpClient();
    static readonly string url = "https://プリザンターのURL/api/items/999999/upsert";
    static readonly string apikey = "プリザンターのAPIキー";

    static async Task Main(string[] args)
    {
        await PostItemAsync();
    }

    static async Task PostItemAsync()
    {
        try
        {

            // リクエストボディを作成
            var requestBody = new
            {
                ApiVersion = 1.1,
                ApiKey = apikey,
                Keys = new string[] { "DescriptionA" }, // コンピュータ名が同じレコードにある場合はレコードを更新、一致するレコードがない場合は新規作成。
                DescriptionHash = new
                {
                    DescriptionA = Environment.MachineName, // コンピュータ名
                    DescriptionB = GetLocalIPAddress(),     // IPアドレス
                    DescriptionC = GetOSName(),             // OS名
                    DescriptionD = GetInstallAppList(),     // インストール済みアプリケーション
                }

            };

            // JSON文字列にシリアライズ
            var json = JsonSerializer.Serialize(requestBody);

            // StringContentを作成
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            // リクエストを送信
            var response = await client.PostAsync(url, content);

            // レスポンスを確認
            response.EnsureSuccessStatusCode();

            // レスポンスボディを読み取る
            var responseBody = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responseBody);
        }
        catch (HttpRequestException e)
        {
            Console.WriteLine(e.Message);
        }
    }

    /// <summary>
    /// インストール済みアプリケーションを取得
    /// </summary>
    /// <returns></returns>
    static string GetInstallAppList()
    {
        StringBuilder sb = new StringBuilder();

        // HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstallを開く
        string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
        {
            foreach (string subkey_name in key.GetSubKeyNames())
            {
                using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                {
                    // アプリケーションの名前を取得して表示
                    sb.AppendLine((string?)subkey.GetValue("DisplayName"));
                }
            }
        }

        return sb.ToString();
    }

    /// <summary>
    /// OSのバージョンを取得
    /// </summary>
    /// <returns></returns>
    static string GetOSName()
    {
        // WMIを使用してOSの情報を取得
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem");
        foreach (ManagementObject o in searcher.Get())
        {
            return o["Caption"].ToString();
        }

        return "";
    }    

    /// <summary>
    /// IPアドレスを取得
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    static string GetLocalIPAddress()
    {
        var host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (var ip in host.AddressList)
        {
            // IPv4アドレスを探す
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                return ip.ToString();
            }
        }

        return "";

    }
}

```

デバッグ実行後、以下の様にデータが登録されていれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/612868c5-cc27-1916-10a2-413f55c4371a.png)