VeeamSqlPerms.psm1
function Set-VeeamPerms { [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline)] [string]$SqlInstance, [Parameter(Mandatory)] [string]$Login, [Parameter()] [switch]$AddLocalAdmin, [Parameter()] [string]$LogPath, [Parameter()] [string]$ExportPath ) process { $results = @() $ConfirmPreference = 'None' $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" function Write-Log { param ($Message) $logEntry = "[$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")] $Message" Write-Host $logEntry if ($LogPath) { Add-Content -Path $LogPath -Value $logEntry } } Write-Log "--- Starting permission assignment for [$Login] on [$SqlInstance] ---" if (-not (Get-DbaLogin -SqlInstance $SqlInstance -Login $Login -ErrorAction SilentlyContinue)) { Write-Log "Creating SQL login: $Login" New-DbaLogin -SqlInstance $SqlInstance -Login $Login -Confirm:$false } else { Write-Log "Login [$Login] already exists." } Write-Log "Assigning server role: dbcreator" Set-DbaLogin -SqlInstance $SqlInstance -Login $Login -AddRole 'dbcreator' -Confirm:$false Write-Log "Granting instance-level permissions..." Invoke-DbaQuery -SqlInstance $SqlInstance -Query @" GRANT CONNECT SQL TO [$Login]; GRANT VIEW ANY DEFINITION TO [$Login]; GRANT VIEW SERVER STATE TO [$Login]; "@ $sysDbGrants = @( @{ Name = "master"; Roles = @" IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'$Login') CREATE USER [$Login] FOR LOGIN [$Login]; EXEC sp_addrolemember N'db_backupoperator', N'$Login'; EXEC sp_addrolemember N'db_datareader', N'$Login'; "@ }, @{ Name = "model"; Roles = @" IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'$Login') CREATE USER [$Login] FOR LOGIN [$Login]; EXEC sp_addrolemember N'db_backupoperator', N'$Login'; EXEC sp_addrolemember N'db_denydatareader', N'$Login'; "@ }, @{ Name = "msdb"; Roles = @" IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N'$Login') CREATE USER [$Login] FOR LOGIN [$Login]; EXEC sp_addrolemember N'db_backupoperator', N'$Login'; EXEC sp_addrolemember N'db_datareader', N'$Login'; EXEC sp_addrolemember N'db_datawriter', N'$Login'; "@ } ) foreach ($item in $sysDbGrants) { try { Write-Log "Configuring system DB [$($item.Name)]" Invoke-DbaQuery -SqlInstance $SqlInstance -Database $item.Name -Query $item.Roles -EnableException } catch { Write-Log "[WARNING] Failed to configure [$($item.Name)]: $_" } } $userDbs = Get-DbaDatabase -SqlInstance $SqlInstance | Where-Object { $_.Name -notin @("master", "model", "msdb", "tempdb") } foreach ($db in $userDbs) { try { $dbName = $db.Name if (-not (Get-DbaDbUser -SqlInstance $SqlInstance -Database $dbName -User $Login -ErrorAction SilentlyContinue)) { Write-Log "Creating user [$Login] in DB [$dbName]" New-DbaDbUser -SqlInstance $SqlInstance -Database $dbName -Login $Login -Username $Login -Confirm:$false } foreach ($role in @("public", "db_backupoperator", "db_denydatareader")) { Add-DbaDbRoleMember -SqlInstance $SqlInstance -Database $dbName -User $Login -Role $role -Confirm:$false -ErrorAction SilentlyContinue Write-Log "Assigned [$role] role in DB [$dbName]" } } catch { Write-Log "[WARNING] Failed to assign roles in [$dbName]: $_" } } if ($AddLocalAdmin) { try { $serverName = ($SqlInstance -split '\\')[0] Write-Log "Adding [$Login] to local Administrators group on [$serverName]" $domain, $username = $Login -split '\\' Invoke-Command -ComputerName $serverName -ScriptBlock { param ($Domain, $Username) $userPath = "WinNT://$Domain/$Username" $group = [ADSI]"WinNT://./Administrators,group" $isMember = $group.psbase.Invoke("IsMember", $userPath) if (-not $isMember) { $group.Add($userPath) Write-Output "Successfully added [$Domain\$Username] to Administrators" } else { Write-Output "[$Domain\$Username] already in Administrators group" } } -ArgumentList $domain, $username | ForEach-Object { Write-Log $_ } } catch { Write-Log "[ERROR] Failed to add [$Login] to local Administrators on ${serverName}: $_" } } Write-Log "✅ Permissions applied for [$Login] on [$SqlInstance]" $results += [PSCustomObject]@{ SqlInstance = $SqlInstance Login = $Login Timestamp = $timestamp LocalAdminAdded = $AddLocalAdmin.IsPresent } # Optional export if ($ExportPath) { $results | Export-Csv -Path $ExportPath -NoTypeInformation -Append Write-Log "Exported summary to $ExportPath" } } } |