Associate User & Logins in Sql Server via Powershell

Quick script to re-associate logins with users that have the same name.  If the user in the database is named the same as the login and has no login currently associated with it, it will set the database user to use the login with the same name.  Apparently, you can’t do this directly via powershell by setting the users’ login to the login name, as it errors out with “Modifying the Login property of the User object is not allowed. You must drop and recreate the object with the desired property.”  Hence the SQL call to sync up the user.

[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum")
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")

$serverName = 'ServerName'

try{
	$srvConn = New-Object "Microsoft.SqlServer.Management.Common.ServerConnection"
	$srvConn.ServerInstance = $serverName
	$srv = New-Object Microsoft.SqlServer.Management.Smo.Server $srvConn
	
	$srv.Logins | where{$_.LoginType -eq [Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin} | %{
		$login = $_
		$srv.Databases | %{
			if($_.Users.Contains($login.Name)){
				$user = $_.Users[$login.Name];
				if($user.Login -eq ''){
<#					#can't do this apparently, smo will only let you drop & re-create...
					$user.Login = $login.Name;
					$user.Alter();
#>
					$_.ExecuteNonQuery("sp_change_users_login 'auto_fix', '" + $user.Name + "'")
				}
			}
		}
	}
}
catch{
	$_ | fl -Force
}

Add a Database Role and Grant EXEC

Quick post on how to add a database role to all your databases and grant EXEC to said role.  This will also add the specified user to said role (aptly named db_exec).  Use with caution, minimally tested.

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
 
$servers = @('ServerName')
$roleName = 'db_exec'
$LoginName = 'LoginName'; 

 
 try{
	foreach($server in $servers){
	 
	    $srv = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $server
	 
	    if (-not $srv.Logins.Contains($LoginName)){ 
	       throw "Login $LoginName does not exist on server $server"
		   return;
		}
		
	    $login = $srv.Logins[$LoginName]
	 
	    foreach($database in $srv.Databases | where{-not $_.IsSystemobject -and $ignoreDBs -notcontains $_.Name -and $_.Status -eq [Microsoft.SqlServer.Management.Smo.DatabaseStatus]::Normal}){
		
			if(-not $database.Users.Contains($login.Name)){
				$user = New-Object('Microsoft.SqlServer.Management.Smo.User') $database, $login.Name
				$user.Login = $login.Name
	        	$user.create();
			}
			
			$user = $database.Users[$LoginName]
			
			if(-not $database.Roles.Contains($roleName)){
				$role = New-Object('Microsoft.SqlServer.Management.smo.DatabaseRole') $database, $roleName
				$role.Create();
			}
			
			$role = $database.Roles[$roleName]
			$role.AddMember($user.Name);
			
			$objDbPerms = New-Object Microsoft.SqlServer.Management.Smo.DatabasePermissionSet 
			$objDbPerms.Execute = $true
			$database.Grant($objDbPerms, $roleName);
			$database.Alter();
	    }
	}
}
catch{
	$_ | fl -Force
}