7
15

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で色々な情報をGlideRecordなどで取得する

Last updated at Posted at 2019-01-26

ほぼ雑記です色々とデータを整理して取得する必要があって効率が良い方法を考え中です

Version: London

sys_domainのカラムを持っているテーブル一覧を作成する

Excelで試す

[System Definition] - [Dictionary]でテーブルのカラム一覧を表示することが出来ます自分の環境だとカラムの数は98,457の様です

image.png

Column name is "sys_domain"を指定してsys_domainを持っているテーブルを一覧表示すると1,360個存在することが分かりました

image.png

リストのヘッダーを右クリックして[Export] - [Excel(.xlsx)]を選択して…

image.png

一応Excelだとこの方法で取得出来ますがこの後で複数のテーブルのデータを色々とjoinしたりして整形したいと思っているのでScriptで簡単に出来ないか考えます

Scriptで試す

こちらの記事でも書いていた[Scripts - BackGround]に移動して

[ServiceNowでJavaのHttpClientを操作する]
https://qiita.com/20_percent_cooler/items/217666f16d3661a90d65

image.png

以下のコードをRun script(JavaScript execute on server)にコピペして

var gr = new GlideRecord("sys_dictionary");
gr.addQuery('element',"sys_domain");
gr.query();
var i = 1;
//var table_list = [];
while (gr.next()) {
gs.info("[" + i + "]," + gr.name + "," +  gr.element);
i++;
}

image.png

[Run script]を実行します

image.png

成功したようです

image.png

親テーブルがsys_domainを持っているものも考慮する

このままの結果でも誤りでは無いのですがテーブルをextendしたテーブルの親がsys_domadinを持っている場合にも対応出来るScriptを考えます親ドメインが存在する場合には再帰的に同じfunctionを呼んでいます

// get table list
var gr = new GlideRecord("sys_db_object");
gr.orderBy('name');
gr.query();
while (gr.next()) {
  gs.log("check sys_domain:" + gr.name);
  check_sys_domain(gr);
}

// check have sys_domain
function check_sys_domain(gr) {
  var grd = new GlideRecord('sys_dictionary');
  grd.addQuery('name', gr.name);
  grd.addQuery('element', 'sys_domain');
  grd.query();
  if (grd.next()) {
    gs.log("have sys_domain:" + gr.name);
  } else {
    gs.log("have no sys_domain:" + gr.name);
    if (gr.super_class) {
      gs.log("-- check parent:" + gr.super_class.name);
      var grs = new GlideRecord("sys_db_object");
      grs.addQuery('name', gr.super_class.name);
      grs.query();
      if (grs.next()) {
        check_sys_domain(grs);
      }
    } else {
      gs.log("OUT");
    }
  }
}

まだ作り途中ですがコピペして置きます

調べるついでに他にも色々と情報がScriptで取得出来たのでコピペして置きます

全てのtableを親子関係込みでScriptで出力する

ER図はこちらの記事で出力方法を書いていますが

[ServiceNowでテーブルを確認/作成する]
https://qiita.com/20_percent_cooler/items/a421efce9fcbfe6335b1

テキストで出力した結果を編集などしたかったので以下で試してみましたこちらも親がある場合には再帰的にfunctionを呼んでいます

gs.log("**** ***** creating all tables tree...");
var gr = new GlideRecord("sys_db_object");
gr.orderBy('name');
gr.query();
var ok_cnt = ng_cnt = 0;
while (gr.next()) {
  var msg = gr.name;
  check_parent(gr);
}
function check_parent(gr) {
  if (gr.super_class) {
    msg = gr.super_class.name + " - "  + msg;
    var grs = new GlideRecord("sys_db_object");
    grs.addQuery('name', gr.super_class.name);
    grs.query();
    if (grs.next())
      check_parent(grs);
  } else {
    gs.log(msg);
  }
}

全てのtableを親子関係込みでACLとroleもScriptで出力する

テーブルのACLとACLについているroleも出してみました

gs.log("**** ***** creating all tables tree and ACL...");
var gr = new GlideRecord("sys_db_object");
gr.orderBy('name');
gr.query();
while (gr.next()) {
    var msg = gr.name;
    check_parent(gr);
    getACL(gr);
}
function check_parent(gr) {
    if (gr.super_class) {
        msg = gr.super_class.name + " - "  + msg;
        var grs = new GlideRecord("sys_db_object");
        grs.addQuery('name', gr.super_class.name);
        grs.query();
    if (grs.next())
        check_parent(grs);
    } else {
        gs.log(msg);
    }
}
function getACL(gr){
    var gsa = new GlideRecord("sys_security_acl");
    var qc = gsa.addQuery('name', gr.name);
    qc.addOrCondition('name','STARTSWITH', gr.name + ".");
    //gsa.addQuery("name", gr.name);
    gsa.query();
    while(gsa.next()){
        var scpt = gsa.script;
        var gsar = new GlideRecord("sys_security_acl_role");
        gsar.addQuery("sys_security_acl", gsa.sys_id);
        gsar.query();
        if (gsar.getRowCount() == 0){
            gs.log(msg + " : " + gsa.name + ":" + gsa.operation); //+ " - " + scpt);
        } else {
            while(gsar.next()){
                gs.log(msg + " : " + gsa.name + ":" + gsa.operation  + " - " + gsar.sys_user_role.getDisplayValue()); //+ " - " + scpt);
            }
        }  
    }
}

全てのroleをcontain含めてScriptで出力する

roleの一覧も欲しくなったので作ってみましたroleの一階層目のcontainに全てのroleが含まれているという前提があっていれば全てのcontainが出ていると思われます(未確認です)

gs.log("**** **** creating all roles tree...");
var gr = new GlideRecord("sys_user_role");
gr.orderBy('name');
//gr.addQuery('role', 'itil');
gr.query();
while (gr.next()) {
  var msg = gr.name.getDisplayValue();
  gs.log(msg);
  get_contain_roles(gr);
}
function get_contain_roles(gr) {
  var grr = new GlideRecord('sys_user_role_contains');
  grr.addQuery('role', gr.sys_id);
  grr.query();
  while(grr.next()){
    gs.log(msg +  " - " + grr.contains.getDisplayValue());
    //get_role(grr);
  }
}
function get_role(grr){
  var grrr = new GlideRecord("sys_user_role");
  grrr.addQuery('sys_id', grr.contains);
  grrr.query();
  if (grrr.next()) {
    get_contain_roles(grrr);
  }
}

Appendix

以降はメモ置き場です

受信したメールのfrom_addressとcopiedのメールアドレスでsys_userのemailを検索して見つかった場合一番古い値を設定して見つからない場合は元のメールアドレスを配列に設定

こういう場合で

image.png

これで

var from = "maguro@example.com";
var cc = ["molamola@example.com", "namerou@example.com", "unknown@example.com"];

var gru = new GlideRecord('sys_user');
var gru_qc = gru.addQuery('email', from);
if (!gs.nil(cc))
  gru_qc.addOrCondition('email', 'IN', cc);
gru.orderBy('sys_created_on');
gru.query();
var obj_gru = new Object();
if (!gru.hasNext()) {
  gs.info("no record");
  //return from + cc;
}
while (gru.next()) {
  obj_gru[gru.email] = gru.name.toString();
}
gs.info( JSON.stringify(obj_gru));
var arr_from_cc = new Array();
arr_from_cc.push(from);
if (!gs.nil(cc)) 
  arr_from_cc = arr_from_cc.concat(cc);
var arr_ret = new Array();
for (var i=0; i<arr_from_cc.length; i++) {
  if (!gs.nil(obj_gru[arr_from_cc[i]])) { 
    arr_ret.push(obj_gru[arr_from_cc[i]]);
    continue;
  } 
  arr_ret.push(arr_from_cc[i]);
}
gs.info(arr_ret);
//return arr_ret;

こう

image.png

削れる配列を削って更に短く

var from = "maguro@example.com";
var cc = ["molamola@example.com", "namerou@example.com", "unknown@example.com"];

var gru = new GlideRecord('sys_user');
var gru_qc = gru.addQuery('email', from);
if (!gs.nil(cc)) //if Cc exist
  gru_qc.addOrCondition('email', 'IN', cc);
gru.orderBy('sys_created_on');
gru.query();
if (!gru.hasNext()) {
  gs.info("no record"); //**** debug
  //return from + cc;
}
var obj_gru = {}; //new Object() for GlideRecord.
while (gru.next()) {
  obj_gru[gru.email.toString()] = gru.name.toString(); //have no same key (key is “email”, value is “name”).
}
gs.info(JSON.stringify(obj_gru)); //**** debug
var arr_from_cc = [from]; //new Array() for return value.
if (!gs.nil(cc)) //if Cc exist
  arr_from_cc = arr_from_cc.concat(cc);
gs.info(arr_from_cc.toString()); //**** debug
for (var i=0; i<arr_from_cc.length; i++) {
  if (!gs.nil(obj_gru[arr_from_cc[i]])) //if “name” exist
    arr_from_cc[i] = obj_gru[arr_from_cc[i]]; //change
}
gs.info(arr_from_cc); //**** debug
//return arr_from_cc;
7
15
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
7
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?