用户管理的脚本代码
作者:Shawn Penner,现就职于SAP
原文地址(英语):
http://scn.sap.com/community/bi-platform/java-sdk/blog/2013/05/14/scripts-for-user-management
当管理一个企业级系统的时候,一个常见场景就是针对系统中所有的用户进行一些共通的变更。以下的脚本代码包含了一些常见的场景,针对一些不能通过简单登陆CMC,InfoView来解决的情形。
警告
下面的代码如果不被正确使用可能会造成严重的后果。因此在使用前请确认您已经充分的对您系统(CMS数据库,Input,Output文件服务器目录)进行了备份。
其中,大部分示例代码以及模板也可以在这个URL找到:http://scn.sap.com/docs/DOC-38620
针对其他脚本以及如何去使用它们,请参考URL:http://scn.sap.com/people/shawn.penner/blog/2013/06/04/scripts-and-samples
有效化/无效化所有的用户
第一个示例脚本可用于实现有效化或无效化系统中所有的用户。其中用户Administrator和Guest是除外的,因为它们是受保护的系统账户因此是不能被修改的。
注意:
- 你可以设定变量disableUsers 为 true 或 false,取决于你的需要。(true=无效化,false=有效化)
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
有效化/无效化所有的用户 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, java.util.*” %> <% // 用户认证信息
// True – 无效化;False – 有效化 IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 用于查询的初始 SI_ID for(;;) { // 除去Administrator and Guest,循环所有用户
// 如果没有对象返回,处理结束. if(boInfoObjects.size() == 0) break;
for(Iterator boCount = boInfoObjects.iterator() ; boCount.hasNext() ; ) { IInfoObject boObject = (IInfoObject)boCount.next(); IUser boUser = (IUser)boObject; Iterator boIterator = boUser.getAliases().iterator(); while(boIterator.hasNext()) { IUserAlias boAlias = (IUserAlias)boIterator.next(); out.println(“current status is: ” + boAlias.isDisabled()); boAlias.setDisabled(disableUsers);
if (disableUsers) { out.println(“user name: ” + boAlias.getName() + ” has been disabled<BR>”); } else { out.println(“user name: ” + boAlias.getName() + ” has been enabled<BR>”); } } max_id = boObject.getID(); } infoStore.commit(boInfoObjects); } %> |
有效化/无效化某个用户组下的用户
第二个示例脚本可用于实现有效化或无效化系统中摸个特定用户组下所有的用户。当然其中用户Administrator和Guest是除外的,因为它们是受保护的系统账户因此是不能被修改的。
注意:
- 你可以设定变量disableUsers 为 true 或 false,取决于你的需要。(true=无效化,false=有效化)
- 你需要更改变量groupName为你希望操作对象的用户组名
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
有效化/无效化某个用户组下的用户 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, com.crystaldecisions.sdk.plugin.desktop.usergroup.*, java.util.*” %> <% // 用户认证信息
// True – 无效化;False – 有效化 IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 取得用户组
if(boInfoObjects.size() == 0) // 没有用户组返回,处理结束 out.println(“No groups found with name ” + groupName); } else { IUserGroup currentGroup = (IUserGroup)boInfoObjects.get(0);
// 取得设定的游标对象 Set boUserList = currentGroup.getUsers(); // 集合包含了对象用户的SI_ID IInfoObjects boInfoObjects2 = (IInfoObjects)infoStore.query(“Select * FROM CI_SYSTEMOBJECTS WHERE SI_ID = ” + boUserIterator.next()); IUser boUser = (IUser)boInfoObjects2.get(0);
// Administrator or Guest 除外 if (boUser.getTitle().equals(“Administrator”) || boUser.getTitle().equals(“Guest”)) { Iterator boIterator = boUser.getAliases().iterator(); while(boIterator.hasNext()) { IUserAlias boAlias = (IUserAlias)boIterator.next(); boAlias.setDisabled(disableUsers);
if (disableUsers) { out.println(“user name: ” + boAlias.getName() + ” has been disabled<BR>”); } else { out.println(“user name: ” + boAlias.getName() + ” has been enabled<BR>”); } } } infoStore.commit(boInfoObjects2); } } %> |
统计报表和实例的个数
接下来这个脚本可用来统计系统中每个用户所拥有的报表数和实例数。该脚本对系统中所有的报表和实例进行循环,然后输出每个用户的结果到一个CSV文件
C:\TestOutput.csv。
注意:
- 你可以更改目标文件夹路径和文件名,你仅需修改这1行代码:“FSout
= new FileOutputStream(“C:\\TestOutput.csv”, true);” - 你需要事先更改username,password,以及CMS名字使它们符合你的系统
统计报表和实例的个数 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, java.util.*, java.io.*” %> <% // 用户认证信息
IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 开始查询的起始 SI_ID writeToLog(“UserID,UserName,ReportsOwned,ReportInstancesOwned”);
for(;;) { // 循环所有用户
// 没有对象返回,处理结束. break;
// 循环所有用户 IInfoObject boObject = (IInfoObject)boCount.next(); int max_id2 = 0; int max_id3 = 0; int countReports = 0; int countInstances = 0;
// 循环所有报表模板,统计用户所有的报表数 for(;;) { IInfoObjects boInfoObjects2 = (IInfoObjects)infoStore.query(“Select * FROM CI_INFOOBJECTS WHERE SI_OWNERID = ” + boObject.getID() + ” AND SI_INSTANCE=0 AND SI_ID > ” + max_id2 + ” AND (SI_KIND=’CrystalReport’ OR SI_KIND=’Webi’ OR SI_KIND = ‘FullClient’) ORDER BY SI_ID ASC”);
// 没有对象返回,处理结束. if(boInfoObjects2.size() == 0) break;
countReports+=countReports + boInfoObjects2.size(); max_id2 = ((IInfoObject)boInfoObjects2.get(boInfoObjects2.size()-1)).getID(); }
// 循环所有报表实例,统计用户所有的报表数 IInfoObjects boInfoObjects3 = (IInfoObjects)infoStore.query(“Select * FROM CI_INFOOBJECTS WHERE SI_OWNERID = ” + boObject.getID() + ” AND SI_INSTANCE=1 AND SI_ID > ” + max_id3 + ” ORDER BY SI_ID ASC”);
// 没有对象返回,处理结束 if(boInfoObjects3.size() == 0) break;
countInstances+=countInstances + boInfoObjects3.size(); max_id3 = ((IInfoObject)boInfoObjects3.get(boInfoObjects3.size()-1)).getID(); }
writeToLog(boObject.getID() + “,” + boObject.getTitle() + “,” + countReports + “,” + countInstances); max_id = boObject.getID(); } } %> <%! public void writeToLog(String msg) { try { // 设定日志文件 FileOutputStream FSout; PrintStream pStream; // 声明打印流对象 FSout = new FileOutputStream(“C:\\TestOutput.csv”, true); // 默认续写 pStream = new PrintStream(FSout); pStream.println(msg); pStream.close(); } catch (IOException e) { // 错误处理 } } %> |
改变报表所有者
接下来这个脚本可用来是的原本属于A用户拥有的所有Crystal
Report,变为另一个B用户所拥有。代码通过设定报表属性SI_OWNERID,从而适用于SI_OWNER。(SI_OWNER是个只读属性无法被直接赋值)
注意:
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
- 你需要事先更改变量sourceUserID和destUserID来匹配你系统中的用户的SI_ID
改变报表所有者 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, java.util.*” %> <% // 用户登录信息
String sourceUserID = “12345”; // SI_ID 源对象用户 (当前所有者)
IEnterpriseSession enterpriseSession = null;
// 登录系统
// 检索初始ID
for(;;) { // 循环所有对象
// 没有对象返回,处理结束. break;
for(Iterator boCount = boInfoObjects.iterator() ; boCount.hasNext() ; ) { IInfoObject boObject = (IInfoObject)boCount.next(); // 需要转换ID为interger,如果不转换,程序不会出错,但是也不会进行处理
out.println(“Changed owner for report ID ” + boObject.getID() + ” with title ” + boObject.getTitle() + “</br>”); max_id = boObject.getID(); } infoStore.commit(boInfoObjects); } %> |
复制用户的全局基本设定
接下来这个脚本可用来是的将某个用户的基本设定内容,复制给指定的用户组下的用户。它同样将系统用户Administrator和Guest除外(如果它属于指定的用户组)。要使用这个脚本,首先设置一个用户使其完成需要的基本设定的设置,然后设定脚本的变量sourceUserID和groupName来执行这个程序。
注意:
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
- 你需要事先更改变量sourceUserID和groupName来匹配你系统中的用户SI_ID及目标用户组组名
复制用户的全局基本设定 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, com.crystaldecisions.sdk.plugin.desktop.usergroup.*, java.util.*” %> <% // 登录信息
String sourceUserID = “12345”;
IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 取得用户组
// 取得源用户
if(boInfoObjects.size() == 0 || boInfoObjects3.size() == 0) { // 找不到目标用户,用户组,则处理结束 if (boInfoObjects.size() == 0) { out.println(“No groups found with name ” + groupName); } else { out.println(“No user found or use” + sourceUserID + ” had null preferences section”); } } else { IUserGroup currentGroup = (IUserGroup)boInfoObjects.get(0);
// 取得源用户的SI_DATA 集合
// 取得对象游标 Set boUserList = currentGroup.getUsers(); // 取得用户组下所有用户 IInfoObjects boInfoObjects2 = (IInfoObjects)infoStore.query(“Select * FROM CI_SYSTEMOBJECTS WHERE SI_ID = ” + boUserIterator.next()); IUser boUser = (IUser)boInfoObjects2.get(0);
// Administrator or Guest 用户除外 { IProperties targetProp = (IProperties)boUser.properties();
// 如果目标用户没有SI_DATA,添加并复制 // 如果存在,则覆写 if (targetProp.getProperty(“SI_DATA”) == null) { out.println(“User ” + boUser.getTitle() + ” had no preferences set – assigning new preferences. </br>”); targetProp.add(“SI_DATA”, sourceProp,0); } else { out.println(“User ” + boUser.getTitle() + ” had some preferences set – overwriting preferences. </br>”); targetProp.add(“SI_DATA”, sourceProp,0); } } infoStore.commit(boInfoObjects2); } } %> |
强制注销所有用户
接下来这个脚本可用来强制注销系统中的用户。它适用于目前系统的同时登录数不多于1000。(这是因为一个CMS查询最多只会返回1000个结果)。因此,如果当前系统有多于1000个登陆数的话,需要你反复执行多次从而将所有的用户注销。这段程序是按照用户session的属性SI_CREATE_TIME来排序,从而确保执行这段代码的用户session是最后被注销的
注意:
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
强制注销所有用户 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, java.util.*” %> <% // 用户登录信息
IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 循环所有对象
for(Iterator boCount = boInfoObjects.iterator() ; boCount.hasNext() ; ) { IInfoObject boObject = (IInfoObject)boCount.next(); out.println(“Removing Session for User ” + boObject.getTitle() + “</br>”); } %> |
移除所有指定类型别名
接下来这个脚本可用来删除系统中所有的指定类型用户别名。它通过获取并比较别名的认证方式,删除指定认证类型的别名。(Administrator和Guest除外)
注意:
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
移除所有指定类型别名 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, java.util.*” %> <% // 用户登录信息
IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 查询初始ID
for(;;) { // 循环除去 Administrator and Guest 的对象
// 没有结果,处理结束 if(boInfoObjects.size() == 0) break;
for(Iterator boCount = boInfoObjects.iterator() ; boCount.hasNext() ; ) { IInfoObject boObject = (IInfoObject)boCount.next(); IUser boUser = (IUser)boObject; Iterator boIterator = boUser.getAliases().iterator(); while(boIterator.hasNext()) { IUserAlias boAlias = (IUserAlias)boIterator.next(); String authentication = boAlias.getAuthentication();
// 如果是secLDAP的别名,则删除 // 可能的别名类型为 “secWinAD”, “secEnterprise”, “secWindowsNT”, “secLDAP” if(“secLDAP”.equals(authentication)) { boUser.getAliases().remove(boAlias); } } max_id = boObject.getID(); } infoStore.commit(boInfoObjects); } %> |
变更用户为命名用户或并行用户
接下来这个脚本可用变更一个用户组下所有的用户为命名用户或并行用户。(Administrator和Guest除外)
注意:
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
- 你需要事先更改变量groupName来匹配你系统中的目标用户组名。(代码里是设为Everyone)
变更用户为命名用户或并行用户 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, com.crystaldecisions.sdk.plugin.desktop.usergroup.*, java.util.*” %> <% // 用户登录信息
int boConnectionType = 1; // 设为 1 (并行用户), 0 (命名用户) String groupName = “Everyone”;
IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 取得用户组
if(boInfoObjects.size() == 0) // 没有用户组返回,退出 } else { IUserGroup currentGroup = (IUserGroup)boInfoObjects.get(0);
//取得游标对象 Set boUserList = currentGroup.getUsers(); // 取得属于组的用户SI_ID IInfoObjects boInfoObjects2 = (IInfoObjects)infoStore.query(“Select * FROM CI_SYSTEMOBJECTS WHERE SI_ID = ” + boUserIterator.next()); IUser boUser = (IUser)boInfoObjects2.get(0);
// Administrator or Guest 除外 if (!(boUser.getTitle().equals(“Administrator”) || boUser.getTitle().equals(“Guest”))) { boUser.setConnection(boConnectionType);
if (boConnectionType == 1) { out.println(“Set ” + boUser.getTitle() + ” user account to Concurrent </br>”); } else { out.println(“Set ” + boUser.getTitle() + ” user account to Named </br>”); }
} infoStore.commit(boInfoObjects2); } } %> |
添加用户别名
接下来这个脚本可用以为指定用户组下的用户添加特定种类的别名(Administrator和Guest除外)
注意:
- 你需要事先更改username,password,以及CMS名字使它们符合你的系统
- 你需要事先更改变量groupName来匹配你系统中的目标用户组名。(代码里是设为Everyone)
- 变量isDisabled用来控制别名添加后是否有效化。设为false来有效化别名,设为true来无效化别名。
- 通过设定变量AliasType来指定别名的种类,请注意它的值是大小写敏感的。可用的值为secEnterprise,
secLDAP, secWinAD, secWindowsNT - kbase 1452123 (https://service.sap.com/sap/support/notes/1452123) 包含了.NET的版
添加用户别名 |
---|
<%@ page import = “com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.framework.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.report.*, com.crystaldecisions.sdk.properties.*, com.crystaldecisions.sdk.plugin.desktop.user.*, com.crystaldecisions.sdk.plugin.desktop.usergroup.*, java.util.*” %> <% // 用户登录信息
String groupName = “Everyone”; // 变更所属用户组名
IEnterpriseSession enterpriseSession = null;
// 登陆系统
// 取得用户组
if(boInfoObjects.size() == 0) // 没有用户组信息,返回 } else { IUserGroup currentGroup = (IUserGroup)boInfoObjects.get(0);
//取得游标对象 Set boUserList = currentGroup.getUsers(); // 用户组所包含用户的SI_ID IInfoObjects boInfoObjects2 = (IInfoObjects)infoStore.query(“Select * FROM CI_SYSTEMOBJECTS WHERE SI_ID = ” + boUserIterator.next()); IUser boUser = (IUser)boInfoObjects2.get(0);
// Administrator or Guest 除外 if (!(boUser.getTitle().equals(“Administrator”) || boUser.getTitle().equals(“Guest”))) { IUserAliases boAliases = boUser.getAliases(); IUserAlias myAlias = boAliases.addExisting(AliasType + “:” + boUser.getTitle(),AliasType + “:#” + boUser.getID(), isDisabled); } infoStore.commit(boInfoObjects2); } } %> |