├── ProvisionAxDeveloper.ps1 ├── README.md └── SECURITY.md /ProvisionAxDeveloper.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Script used to provision users to use Dynamics AX Developer Tools. 4 | 5 | .DESCRIPTION 6 | Script used to provision users to use Dynamics AX Developer Tools. The current user must be part of Administrators group to run this script as well to use 7 | Dynamics AX Developer tools. This script creates a Sql Server logins with user[s] provided as arguments and creates corresponding user[s] for Dynamics Xref 8 | database. 9 | 10 | .NOTES 11 | Name: ProvisionAxDeveloper 12 | Author: Microsoft 13 | DateCreated: 11Jan2016 14 | 15 | .EXAMPLE 16 | ProvisionAxDeveloper.ps1 ,,... 17 | 18 | 19 | Description 20 | ----------- 21 | The user who runs this command must be an administrator. On running this command we will check if the users given in the arguments 22 | are part of administrators group. If the check passes we will go provision the Dynamics AX Developer Tools for all provided users. If any 23 | of the users are not part of administrators group we will fail the script in the validation phase itself. 24 | 25 | Disclaimer: 26 | This code is made available AS IS and is not supported by Microsoft. 27 | The risk of the use or the results from the use of this code remains with the user. 28 | #> 29 | [cmdletbinding()] 30 | Param( 31 | [Parameter(Mandatory=$True)] 32 | [string] $databaseServerName, 33 | [Parameter(Mandatory=$True)] 34 | [string[]] $users 35 | ) 36 | 37 | $AdminUsers = {} 38 | 39 | # 40 | # Check if the current user has admin privileges. User must be an administrator or part of builtin\administrators group 41 | # 42 | Try 43 | { 44 | $AdminUsers = invoke-command { net localgroup administrators | where {$_ -AND $_ -notmatch "command completed successfully"} | select -skip 4 } 45 | 46 | $identity = [Security.Principal.WindowsIdentity]::GetCurrent() 47 | $principal = New-Object Security.Principal.WindowsPrincipal -ArgumentList $identity 48 | $userName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name 49 | 50 | If(($principal.IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator ) -eq $false) -AND ($AdminUsers -contains $userName -eq $false )) 51 | { 52 | Write-Host "You must be an administrator to run this script" 53 | return -1 54 | } 55 | } 56 | Catch 57 | { 58 | $ErrorRecord = $Error[0] 59 | $ErrorRecord | Format-List * -Force 60 | $ErrorRecord.InvocationInfo |Format-List * 61 | $Exception = $ErrorRecord.Exception 62 | 63 | For ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException)) 64 | { "$i" * 80 65 | $Exception |Format-List * -Force 66 | } 67 | Throw "Failed to determine if the current user has elevated privileges. The error was: '{0}'." -f $_ 68 | } 69 | 70 | If($PSBoundParameters.Count -lt 1) 71 | { 72 | Write-Host "Usage: \n PrepareAxTools.ps1 ,,...\n Users must be part of Administrators group" 73 | return -1 74 | } 75 | 76 | $AdminUsers = Invoke-command { net localgroup administrators | where {$_ -AND $_ -notmatch "command completed successfully"} | select -skip 4 } 77 | 78 | # 79 | # Validate if the user[s] argument are part of Administrators group 80 | # 81 | 82 | #Begin Validation 83 | $quit = $false 84 | 85 | Foreach ($user in $users) 86 | { 87 | $userNameComponents = $user.Split('\') 88 | $username = '' 89 | $domain = '' 90 | 91 | If($userNameComponents.Count -eq 2) 92 | { 93 | $domain = $userNameComponents[0] 94 | $username = $userNameComponents[1] 95 | 96 | # 97 | # For the local user accounts, windows does not store the Computer Name in the administrators user group. 98 | # 99 | If($domain -eq $env:computername) 100 | { 101 | $user = $username 102 | } 103 | } 104 | Else 105 | { 106 | Write-Host "Invalid format. User name must of format 'domain or hostname\username'" 107 | return -1 108 | } 109 | 110 | If(-NOT ($AdminUsers -contains $user)) 111 | { 112 | Write-Host $user "is not part of Administrators group." 113 | $quit = $true 114 | } 115 | } 116 | 117 | If($quit -eq $true) 118 | { 119 | Write-Host "Users must be part of Administrators group. Please add the user[s] to builtin\Administrators group and re-run the script" 120 | return -1 121 | } 122 | #End Validation 123 | 124 | # 125 | # Provision SQL access to the users 126 | # 127 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | out-null 128 | $databaseServerName = $env:databaseServerName 129 | $ManagedComputer = New-Object ('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer') $databaseServerName 130 | 131 | $serverInstance = "" 132 | 133 | 134 | # 135 | # Provision user access 136 | # 137 | 138 | #Begin Provision 139 | Foreach($user in $users) 140 | { 141 | Try 142 | { 143 | 144 | $sqlSrv = New-Object 'Microsoft.SqlServer.Management.Smo.Server' "$databaseServerName" 145 | 146 | $login = $sqlSrv.Logins.Item($user) 147 | $dbName = "DYNAMICSXREFDB" 148 | $database = $sqlSrv.Databases[$dbName] 149 | $dbRoleName = "db_owner" 150 | $dbRole = $database.Roles[$dbRoleName] 151 | 152 | If(-Not ($login)) 153 | { 154 | $login = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $sqlSrv, $user 155 | $login.LoginType = "WindowsUser" 156 | $login.Create() 157 | 158 | } 159 | else 160 | { 161 | Write-Host "User $user already exists" 162 | } 163 | 164 | If(-Not ($login.IsMember("sysadmin"))) 165 | { 166 | $login.AddToRole("sysadmin") 167 | $login.Alter() 168 | $sqlSrv.Refresh() 169 | } 170 | else 171 | { 172 | Write-Host "User $user is already a member of sysadmin" 173 | } 174 | 175 | If(-Not $database.Users[$user] ) 176 | { 177 | # 178 | # Map the user to database 179 | # 180 | $sql = "CREATE USER `"$user`" FOR LOGIN `"$user`" WITH DEFAULT_SCHEMA=[dbo]; 181 | EXEC sp_addrolemember 'db_owner', `"$user`"" 182 | $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 183 | $sqlConnection.ConnectionString = "server=$databaseServerName;integrated security=TRUE;database=$dbName" 184 | $sqlConnection.Open() 185 | $sqlCommand = new-object System.Data.SqlClient.SqlCommand 186 | $sqlCommand.CommandTimeout = 120 187 | $sqlCommand.Connection = $sqlConnection 188 | $sqlCommand.CommandText= $sql 189 | $text = $sql.Substring(0, 50) 190 | Write-Progress -Activity "Executing SQL" -Status "Executing SQL => $text..." 191 | Write-Host "Executing SQL => $text..." 192 | $result = $sqlCommand.ExecuteNonQuery() 193 | $sqlConnection.Close() 194 | } 195 | else 196 | { 197 | Write-Host "User $user is already mapped to database $database" 198 | } 199 | } 200 | Catch 201 | { 202 | $ErrorRecord = $Error[0] 203 | $ErrorRecord | Format-List * -Force 204 | $ErrorRecord.InvocationInfo |Format-List * 205 | $Exception = $ErrorRecord.Exception 206 | 207 | for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException)) 208 | { "$i" * 80 209 | $Exception |Format-List * -Force 210 | } 211 | 212 | Throw "Failed to provision database access for the user: $user" 213 | } 214 | } 215 | #End Provision 216 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dynamics-AX-Scripts 2 | Scripts for Dynamics AX environments. 3 | 4 | ##ProvisionAxDeveloper.ps1 5 | When a Microsoft Dynamics AX environment is first deployed, only one user account is enabled as a developer on the virtual machine (VM). This script lets you add another developer account. For more information, see [Enable a new developer on a Dynamics AX development machine](https://ax.help.dynamics.com/en/wiki/enable-a-new-developer-on-a-dynamics-ax-development-machine/). 6 | 7 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | --------------------------------------------------------------------------------