Did you try this in NAV2009? In NAV2009 you can use only domain users. When you put user ID in table, you need put user SID also.
I am using NAV 2018 in 2024. This comment helped me so much. I automated creation of a NAV user in Users, but was stuck on setting user personalization settings. The whole time I was using a test user not in AD on a test server. Once I I switched to testing with a user that was in AD, everything fell into place. This is the python code I use. I would have felt bad not to post it. I have removed all sensitive information. More information like this should be available online. Maybe this will help someone in the future. One day it took me 2 hours to add many users and this just takes seconds if you change the information and make templates. I will be creating an intranet site to manage this in the future.
import os
from zeep import Client, exceptions, xsd, Plugin
from zeep.transports import Transport
from requests_ntlm import HttpNtlmAuth
from zeep.helpers import serialize_object
import requests
import constants
import winrm
import time
class IgnoreUnexpectedElementsPlugin(Plugin):
def ingress(self, envelope, http_headers, operation):
body = envelope.find('{http://schemas.xmlsoap.org/soap/envelope/}Body')
if body is not None:
response_element = body[0]
if response_element.tag.endswith('Read_Result'):
karl_user_card_element = response_element.find(
'{urn:microsoft-dynamics-schemas/page/karl_user_card}Karl_User_Card'
)
if karl_user_card_element is not None:
for child in karl_user_card_element:
if child.tag.endswith('ACSStatus') or child.tag.endswith('AuthenticationStatus'):
karl_user_card_element.remove(child)
return envelope, http_headers
def clear_terminal():
os.system('cls' if os.name == 'nt' else 'clear')
# Setup
clear_terminal()
admin_username, admin_password = constants.user_pass()
admin_username = f'Domain\\{admin_username}'
# User details and groups for new NAV user
new_user_username = 'Domain\\testman'
new_user_full_name = 'Test Estman'
new_user_license_type = 'Full'
new_user_state = 'Enabled'
company = 'company in NAV'
# Remote server credentials and details - Test
soap_server = 'soap server'
remote_server = 'Server'
server_instance = 'ServerInstance'
# Adjusted PowerShell script to execute
ps_script = f"""
$serverName = '{server_instance}'
$username = '{new_user_username}'
$fullName = '{new_user_full_name}'
$licenseType = '{new_user_license_type}'
$state = '{new_user_state}'
$modulePath = 'C:\\Program Files\\Microsoft Dynamics NAV\\110\\Service\\NavAdminTool.ps1'
Import-Module $modulePath
Get-NAVServerInstance -ServerInstance $serverName
New-NAVServerUser -ServerInstance $serverName -Username $username -FullName $fullName -LicenseType $licenseType -State $state
"""
# Create session and execute script
session = winrm.Session(remote_server, auth=(admin_username, admin_password), transport='ntlm')
result = session.run_ps(ps_script)
# Output the result
#print("STDOUT:", result.std_out.decode())
#print("STDERR:", result.std_err.decode())
##########################################################################################################
##########################################################################################################
# User details to add to the groups
# SOAP Service Setup
# The names at the end come from the soap url in web services
# Karl is my manager
users_wsdl_url = f'{soap_server}{company}/Page/Karl_Users'
user_card_wsdl_url = f'{soap_server}{company}/Page/Karl_User_Card'
wsdl_url_user_Personalization = f'{soap_server}{company}/Page/Karl_User_Personalization'
wsdl_url_user_Person_Card = f'{soap_server}{company}/Page/Karl_User_Person_Card'
##########################################################################################################
session = requests.Session()
session.auth = HttpNtlmAuth(admin_username, admin_password)
transport_with_ntlm = Transport(session=session)
plugin = IgnoreUnexpectedElementsPlugin()
##########################################################################################################
# Create Zeep clients with the custom plugin
users_client = Client(wsdl=users_wsdl_url, transport=transport_with_ntlm)
user_card_client = Client(wsdl=user_card_wsdl_url, transport=transport_with_ntlm, plugins=[IgnoreUnexpectedElementsPlugin()])
user_personalization_client = Client(wsdl=wsdl_url_user_Personalization, transport=transport_with_ntlm, plugins=[plugin])
user_person_card_client = Client(wsdl=wsdl_url_user_Person_Card, transport=transport_with_ntlm, plugins=[plugin])
##########################################################################################################
# Initialize user_security_id with a default value
user_security_id = None
# Use the Users URL to get the security ID based on the username
username_filter = {'Field': 'User_Name', 'Criteria': f'{new_user_username}'}
user_list = users_client.service.ReadMultiple(filter=username_filter, setSize=1)
# Assuming user_list is successfully retrieved and contains at least one user
if user_list:
user_card_fetched = user_list[0]
user_security_id = user_card_fetched.User_Security_ID
user_key = user_card_fetched.Key # Capture the Key from the original retrieval
print(f'User Security ID: {user_security_id}')
if user_security_id is not None:
try:
# Here we begin the reconstruction of the user_card for the update
# Assuming 'ns0' is the correct namespace
user_group_factory = user_card_client.type_factory('ns0')
# Recreate the user_card object for the update, including all required fields
user_card = user_group_factory.Karl_User_Card(
Key=user_key, # Reuse the Key captured from the initial fetch
# Include other necessary fields from the fetched user_card
User_Name=user_card_fetched.User_Name,
Full_Name=user_card_fetched.Full_Name,
State=user_card_fetched.State,
License_Type=user_card_fetched.License_Type,
# Add or modify fields as needed based on your specific requirements
)
# Prepare the User_Groups_User_SubPage_List object with the new group(s)
# This is just an example. I changed it to PRODUCTION for this example, but could be any of your groups.
# We add user permissions to groups and those groups are what is being applied here.
# 1 group is added here and you can add more by using curly brackets.
# These permissions will appear on the user card for the user once selected in Users
new_user_group = user_group_factory.User_Groups_User_SubPage(
UserGroupCode='PRODUCTION',
User_Group_Name='Production',
Company_Name=company
)
# Assign the new user group to the user_card
# Here, ensure UserGroups is properly initialized or updated based on your scenario
user_card.UserGroups = user_group_factory.User_Groups_User_SubPage_List(User_Groups_User_SubPage=[new_user_group])
try:
# Now, attempt to update the user card with the modified details
update_response = user_card_client.service.Update(Karl_User_Card=user_card)
if update_response:
print("User groups updated successfully.")
else:
print("Failed to update user groups.")
except Exception as e:
# Silently handle the specific exception
if "Other user has modified" in str(e):
pass # Do nothing and continue execution
else:
raise # Re-raise the exception for other errors
except Exception as e:
print(f"An error occurred: {e}")
else:
print("Unable to proceed without a User Security ID.")
else:
print("No user found with the specified criteria.")
##########################################################################################################
# Create a new Zeep client for the Karl_User_Person_Card_Available_Profiles service
available_profiles_wsdl_url = f'{soap_server}{company}/Page/Karl_User_Person_Card_Available_Profiles'
available_profiles_client = Client(wsdl=available_profiles_wsdl_url, transport=transport_with_ntlm)
if user_security_id is not None:
try:
# Here we begin the construction of a new user person card
user_person_card_factory = user_person_card_client.type_factory('ns0')
# Create the user person card with the required fields and the selected profile
user_person_card = user_person_card_factory.Karl_User_Person_Card(
User_ID=new_user_username, # Use the appropriate user ID
# ProfileID='COLORTECH PRODUCTION', # Set the desired profile ID
Language_ID=1033, # English - United States
Locale_ID=1033, # English - United States
Time_Zone='Eastern Standard Time',
Company=company,
)
# Now, attempt to create the user person card using Create
try:
create_response = user_person_card_client.service.Create(Karl_User_Person_Card=user_person_card)
if create_response:
print("User personalization entry created successfully.")
else:
print("Failed to create user personalization entry.")
except Exception as ex:
print(f"An error occurred while creating user personalization entry: {str(ex)}")
# Log the exception details or perform additional error handling
except Exception as e:
print(f"An error occurred: {str(e)}")
# Log the exception details or perform additional error handling
else:
print("Unable to proceed without a valid User Security ID.")