Skip To Content

例: メンバーをポータルに追加する

この例では、ユーザーに関する情報を含む入力テキスト ファイルを受け取って、それらを一括してポータルに追加します。 ポータルで各ユーザーのロールを定義し付与します。

スクリプトの実行時に、以下の必須情報を入力します。

  • ユーザー情報を含むテキスト ファイルへのパス (例: C:\users.txt)。
  • ポータルに追加するユーザーのタイプ (たとえば、「組み込み」や「エンタープライズ」)。 ユーザーのタイプの詳細については、「ポータルへのアクセスの管理」をご参照ください。
  • ポータルをホストするコンピューターの完全修飾ドメイン名 (たとえば、「myportal.acme.com」)。 このスクリプトは、ArcGIS Web Adaptor を迂回し、ポート 7443 で HTTPS を経由してポータルにアクセスします。 このように、ポータルが Web 層認証を使用するように構成されている場合、スクリプトで Web 層認証を処理する必要はありません。
  • ポータルに対する管理権限を持つアカウントのユーザー名とパスワード。 組み込みアカウントを追加する場合、ポータルの管理権限を持つ任意のメンバーの認証情報を入力します。 組織固有のアカウントを追加する場合、Portal for ArcGIS のインストール後に作成された初期管理者アカウントを使用します。
注意:

Python スクリプトで Web 層認証を処理する方法に関しては、この例では扱いません。

エンタープライズ アカウントの登録

エンタープライズ アカウントを登録する場合、テキスト ファイル内の各エントリの形式は次のようになります。

<login>|<email address>|<name>|<role>|<description>|<Idp UserName>

  • login - 登録するエンタープライズ ログイン。

    • Active Directory を使用する場合、このログインの形式は sAMAccountName@DOMAIN です。 ドメイン名はすべて大文字にする必要があります。
    • LDAP を使用する場合、ログインは、アイデンティティ ストアの構成時に指定した「userNameAttribute」の値と同じです。
    • SAML ベースのエンタープライズ ログインを使用する場合、指定されたログイン値は、SAML ID プロバイダーの NameID 属性と同じです。
  • email address - login に関連付けられている電子メールであり、アイデンティティ ストアの値と同じです。 ユーザー アカウントに電子メール アドレスがない場合、仮のまたは汎用的な値を指定します。

  • name - login に対応する、ArcGIS 組織内で使用されるエイリアスです。 アイデンティティ ストアの大半は、ユーザーの氏名をデフォルトのエイリアスとして使用します。 ユーザーがポータル Web サイトに接続した場合は、この名前が Web サイトの上部に表示されます。

  • ユーザー タイプ - ユーザーが割り当てられるユーザー タイプの名前。 ドロップダウン リストから任意のユーザー タイプを選択します。 互換性のあるロールとアドオン ライセンス数をクリックして、選択したユーザー タイプとの互換性についての詳細を調べることができます。 詳細については、「ユーザー タイプ、ロール、権限」をご参照ください。
  • role - これは、エンタープライズ ログインに対して ArcGIS 組織内で割り当てられるロールです。 有効なロールの値は、userpublisheradmin、または <custom_role_name> です。<custom_role_name> は、カスタム ロールの名前 (たとえば、hostedservicepublisher) です。

    レガシー:

    Portal for ArcGIS 10.3 以前のバージョンでは、カスタム ロール以外に使用できる値は org_userorg_publisherorg_admin でした。 10.3.1 では、これらの値は廃止され、上記の値に置き換えられました。 10.3.1 でも従来の値を使用できますが、今後のリリースでは使用できなくなる可能性がありますので注意してください。

  • description - 必要に応じて、アカウントを説明するテキストを含めます。 この値は、アイデンティティ ストアのどの属性とも対応しません。 description は 250 文字を超えることはできません。

  • Idp UserName - オプションで、アイデンティティ プロバイダーにエンタープライズ アカウントの名前を指定します。 この値を指定しない場合、代わりにログイン パラメーターに指定した値が使用されます。

ユーザーは、login、email address、name、および role を指定する必要があります。 説明および Idp UserName はオプションです。 ファイルにリスト表示されている各アカウントでは、login、email address、および name に入力した値は、アイデンティティ ストアの値と完全に一致している必要があります。 ポータルは、アイデンティティ ストアに接続してこれらの値を確認しません。

次に、Active Directory エンタープライズ アカウントを登録するエントリの例を示します。login は jcho111、email address は jcho@domain.com、full name は Jon Cho です。 この login はユーザー ロール (user) および Viewer ユーザー タイプ内に格納され、このユーザーが department b に所属しているという説明を記述します。

jcho111@DOMAIN|jcho@domain.com|Jon Cho|Viewer|user|department b

次に、SAML アイデンティティ プロバイダーからエンタープライズ アカウントを登録するエントリの例を示します。 ユーザーの login は rsmith@domain.com で、email address は rsmith@domain.com で、full name は Robert Smith です。 login は、公開者ロール (publisher) および Creator ユーザー タイプ内に格納され、Idp UserName は rsmith@domain.com です。

rsmith@domain.com|rsmith@domain.com|Robert Smith|Creator|publisher||rsmith@domain.com

次に、LDAP エンタープライズ アカウントを登録するエントリの例を示します。login は sjames4513、email address は sjames@domain.com、full name は Sara James です。 この login はユーザー ロール (admin) および GIS Professional ユーザー タイプ内に格納され、説明が入力されます。

sjames4513@DOMAIN|sjames@domain.com|Sara James|GISProfessional|admin|Department Lead and GIS Manager

次に、エンタープライズ アカウントを登録するエントリの例を示します。login は srajhandas、email address は srajhandas@domain.com、full name は Satish Rajhandas です。 この login は、ユーザー ロール (user) および Viewer ユーザー タイプ内に格納されます。

srajhandas@DOMAIN|srajhandas@domain.com|Satish Rajhandas|Viewer|user

次に、SAML アイデンティティ プロバイダーからエンタープライズ アカウントを登録するエントリの例を示します。 ユーザーの login は djohnson308 で、email address は djohnson@domain.com で、full name は Daisha Johnson です。 この login はユーザー ロール (user) および Creator ユーザー タイプ内に格納され、説明が入力され、Idp UserName が djohnson@domain.com と入力されます。

djohnson308@DOMAIN|djohnson@domain.com|Daisha Johnson|Creator|user|Account Specialist|djohnson@domain.com

組み込みポータル アカウントの追加

組み込みのポータル アカウントを登録する場合は、テキスト ファイル内の各エントリの形式は次のようになります。

<username>|<password>|<email address>|<name>|<user type>|<role>|<description>

  • username - 組み込みアカウントに使用されるユーザー名。 ユーザー名は一意である必要があります。2 人のメンバーが同じユーザー名を持つことはできません。
  • password - アカウントに割り当てられるパスワード。 ユーザーはポータルに最初にサイン インするときにこのパスワードを使用でき、その後、自分のプロファイルを編集してパスワードを変更することができます。
  • email address - このアカウントに対応する電子メール アドレスを指定します。 このパラメーターは必須です。したがって、有効なアドレスでなくても、email address に値を指定する必要があります。
  • name - ArcGIS 組織内で使用されるアカウントに対応するエイリアスです。 ユーザーがポータル Web サイトに接続した場合は、この名前がポータル Web サイトの上部に表示されます。
  • ユーザー タイプ - ユーザーが割り当てられるユーザー タイプの名前。 ドロップダウン リストから任意のユーザー タイプを選択します。 互換性のあるロールとアドオン ライセンス数をクリックして、選択したユーザー タイプとの互換性についての詳細を調べることができます。 詳細については、「ユーザー タイプ、ロール、権限」をご参照ください。
  • role - ArcGIS 組織内でアカウントに対して割り当てられるロールです。 有効なロールの値は、user、publisher、admin、または <custom_role_name> です。<custom_role_name> は、カスタム ロールの名前 (たとえば、hostedservicepublisher) です。
  • description - 必要に応じて、アカウントを説明するテキストを含めます。 description は 250 文字を超えることはできません。

次の例では組み込みのポータル アカウントを追加します。Barbara Williams に対応するユーザー名は pub1、アカウントの email は bwilliams@domain.com です。 また、pub1 を公開者ロールに追加します。

pub1|changepasswordlater|bwilliams@domain.com|Barbara Williams|Creator|publisher

次の例では組み込みのポータル アカウントを追加します。Barbara Williams に対応するユーザー名は jcho、アカウントの email は jcho@domain.com です。 また、jcho を管理者ロールに追加して、そのユーザーが GIS マネージャーであるという説明を加えます。

jcho|changepasswordlater|jcho@domain.com|Jon Cho|GISProfessional|admin|GIS Manager

#!/usr/bin/env python
# Requires Python 2.7+

# Demonstrates how to add users to the ArcGIS Enterprise portal in bulk

# For Http calls
import urllib2, urllib, json
# For system tools
import sys, os
# For reading passwords without echoing
import getpass
# Other utilities
import Queue

# Defines the entry point into the script
def main(argv):

    print "This script adds users in bulk into a portal. \n"

    #Get parameters
    parameters = getParametersFromUser ()

    portalURL = parameters['portalURL']
    provider = parameters['provider']
    userName = parameters['userName']
    password = parameters['password']
    inUserFile = parameters['inUserFile']


    #Get user data from file
    usersData = getUserDataFromFile(inUserFile,provider)

    #Create users
    createUsers (userName,password, portalURL,provider, usersData)

    raw_input('Press ENTER to close the script.')

    return


# This function loads all the user data in the input text file into a Python Queue.
# This usersQueue can be later passed to the createUsers function
def getUserDataFromFile(inUserFile,provider):

    usersQ = Queue.Queue()
    inFileHandle = open(inUserFile, 'r')
    userCount = 0
    print '...Processing input users file at: ' + inUserFile
    entryCount = 1
    roleID = {'admin':'org_admin', 'publisher':'org_publisher', 'user':'org_user', 'viewer':'iAAAAAAAAAAAAAAA'}
    for line in inFileHandle.readlines():
        userParams = line.strip('\n').split('|')
        userParamDict = {}
        if provider=="enterprise":
            keyParams = ['username', 'email', 'fullname', 'role', 'userLicenseTypeId', 'description', 'idpUsername', 'firstname', 'lastname']
            if len(userParams) == len(keyParams):
                for i, param in enumerate(keyParams):
                    userParamDict[param] = userParams[i]
                if userParamDict['role'] in roleID.keys():
                    userParamDict['role'] = roleID[userParamDict['role']]
                else:
                    print('The value for the user role "{}" in users text file is invalid.'.format(userParamDict['role']))
                    print('Accepted values are viewer, user, publisher, or admin.')
                    raise SystemExit('Invalid user role')
                usersQ.put(userParamDict)
                userCount = userCount + 1
            else:
                print('The format for entry "{}" is invalid.\nThe format for enterprise accounts is:'.format(line.strip('\n')))
                print(' <login>|<email address>|<full name>|<role>|<user type id>|<description>|<idp username>|<first name>|<last name>')
                raise SystemExit('Invalid format')
        elif provider=="arcgis":
            keyParams = ['username', 'password', 'email', 'fullname', 'role', 'userLicenseTypeId', 'description', 'firstname', 'lastname']
            if len(userParams) == len(keyParams):
                for i, param in enumerate(keyParams):
                    userParamDict[param] = userParams[i]
                if userParamDict['role'] in roleID.keys():
                    userParamDict['role'] = roleID[userParamDict['role']]
                else:
                    print('The value for the user role "{}" in users text file is invalid.'.format(userParamDict['role']))
                    print('Accepted values are viewer, user, publisher, or admin.')
                    raise SystemExit('Invalid user role')
                usersQ.put (userParamDict)
                userCount = userCount + 1
            else:
                print('The format for entry "{}" is invalid.\nThe format for built-in accounts is:'.format(line.strip('\n')))
                print(' <account>|<password>|<email address>|<full name>|<role>|<description>|<first name>|<last name>|<level>')
                raise SystemExit('Invalid format')
        else:
            raise SystemExit( 'The value for the user type is invalid. ')
        entryCount = entryCount +1
    inFileHandle.close()
    # Create users and report results
    print '...Total members to be added: ' + str(userCount)

    return usersQ


# This function connects to the portal and adds members to it from a collection
def createUsers(username,password, portalUrl, provider,userParamsQ):

    print '...Connecting to ' + portalUrl
    token = generateToken(username,password, portalUrl)
    print '...Adding users '
    usersLeftInQueue = True
    while usersLeftInQueue:
        try:
            userDict = userParamsQ.get(False)
            userDict['f'] = 'json'
            userDict['token'] = token
            userDict['provider'] = provider
            params = urllib.urlencode(userDict)

            request = urllib2.Request(portalUrl + '/portaladmin/security/users/createUser?',params, { 'Referer' : portalUrl })

            # POST the create request
            response = urllib2.urlopen(request).read()
            responseJSON = json.loads(response)

            # Log results
            if responseJSON.has_key('error'):
                errDict = responseJSON['error']
                if int(errDict['code'])==498:
                    message = 'Token Expired. Getting new token... Username: ' + userDict['username'] + ' will be added later'
                    token = generateToken(username,password, portalUrl)
                    userParamsQ.put(userDict)
                else:
                    message =  'Error Code: %s \n Message: %s' % (errDict['code'], errDict['message'])
                print '\n' + message
            else:
                # Success
                if responseJSON.has_key('status'):
                    resultStatus = responseJSON['status']
                    print 'User: %s account created' % (userDict['username'])
        except Queue.Empty:
              usersLeftInQueue = False

# This function gets a token from the portal
def generateToken(username, password, portalUrl):
    parameters = urllib.urlencode({'username' : username,
                                   'password' : password,
                                   'client' : 'referer',
                                   'referer': portalUrl,
                                   'expiration': 60,
                                   'f' : 'json'})
    try:
        response = urllib.urlopen(portalUrl + '/sharing/rest/generateToken?',
                              parameters).read()
    except Exception as e:
        raise SystemExit( 'Unable to open the url %s/sharing/rest/generateToken' % (portalUrl))
    responseJSON =  json.loads(response.strip(' \t\n\r'))
    # Log results
    if responseJSON.has_key('error'):
        errDict = responseJSON['error']
        if int(errDict['code'])==498:
            message = 'Token Expired. Getting new token... '
            token = generateToken(username,password, portalUrl)
        else:
            message =  'Error Code: %s \n Message: %s' % (errDict['code'],
            errDict['message'])
            raise SystemExit(message)
    token = responseJSON.get('token')
    return token

# This function gets gets parameters from the user in interactive mode
def getParametersFromUser():

    parameters = {}
    # Get Location of users file
    inUserFile = raw_input ("Enter path to users text file: ")
    if not os.path.exists(inUserFile):
        raise SystemExit( 'Input file: %s does not exist' % (inUserFile))
    parameters['inUserFile'] = inUserFile

    # Enteprise logins or built-in accounts?
    userInput = raw_input ("What type of users do you want to add to the portal?  Accepted values are built-in or enterprise: ")
    if userInput.lower()=="built-in":
        parameters['provider'] = 'arcgis'
        print '   Built-in accounts will be added to the portal. \n'
    elif userInput.lower()=="enterprise":
        parameters['provider'] = 'enterprise'
        print '   Enterprise accounts will be added to the portal. \n'
    else:
        raise SystemExit( 'The value entered for the user type %s is invalid.  Accepted values are built-in or enterprise. ' % (userInput))

    # Get Portal URL
    hostname = raw_input("Enter the fully qualified portal hostname (for example myportal.acme.com): ")
    parameters['portalURL'] = 'https://' + hostname + ':7443/arcgis'
    print '   Users will be added to portal at: ' + parameters['portalURL'] + '\n'

    # Get a username and password with portal administrative privileges
    parameters['userName'] = raw_input("Enter a built-in user name with portal administrative privileges: ")

    parameters['password'] = getpass.getpass("Enter password: ")
    print '\n'

    return  parameters

# Script start
if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))