Automatic configuration of ssrs with power shell - powershell

i have already installed Report server database. I know how to configure Report server through RS Configuration Manager, but i want to do this automatically with power shell.
So how to change these thing:
Change data source connection string
Backup and restore encryption key (i will have Report server on two instances and will have RS in sync)
Change rsconfig file (modify Authentication types, add 2 more for Kerberos)

You can do it by Get-WMIObject with the configuration settings for the SSRS 2017 instance and then setting the required configuration
Get-WmiObject –namespace "root\Microsoft\SqlServer\ReportServer\RS_SSRS\v14\Admin" -class MSReportServer_ConfigurationSetting -ComputerName localhost
connect to the machine
$conn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection -ArgumentList $env:ComputerName
$conn.ApplicationName = "SSRS Configuration Script"
$conn.StatementTimeout = 0
$conn.Connect()
$smo = New-Object Microsoft.SqlServer.Management.Smo.Server -ArgumentList $conn
and change the configuration as required
## Create the ReportServer and ReportServerTempDB databases
$db = $smo.Databases["master"]
$db.ExecuteNonQuery($dbscript)
## Set permissions for the databases
$dbscript = $configset.GenerateDatabaseRightsScript($configset.WindowsServiceIdentityConfigured, "ReportServer", $false, $true).Script
$db.ExecuteNonQuery($dbscript)
## Set the database connection info
$configset.SetDatabaseConnection("(local)", "ReportServer", 2, "", "")
You can modify the script for other two things #2 & #3. Refer this article for more details. hope that should help.

Related

Programmatically Deploying Power BI Reports to Power BI Report Server and change Connection String

Is there any method to deploy Power BI reports to Power BI Report Server without having to manually copy these files, upload them to the server and finally change the data source connectivity information for each report on a report by report basis which is not practical in each customer sites.
Eg. PowerBI Report File - 'Report_1' need to Deploy on Customer server S1, S2, S3, & so on.
Now we doing manually copy these files, upload them to the server and finally change the data source connectivity information for each report on a report by report basis which is not practical in each customer sites.
How we can automate the deployment of PBIX reports to Power BI Report Server and changing Datasource connection string Pro-grammatically.?
Microsoft releasing feature in 2020 Jan to update connection string using API.
Microsoft releasing feature in 2020 Jan. But There is any way in 2019 ? any other way for update connection string ?
Microsoft Link
Finally invented one trick to update Connection String in PowerBI.
First Install PowerBI API in Powershell.
Microsoft API don’t give ability to update connection string but give permission to update username.
Both username and connection string are stored in encrypted format in database.
So logic is pass connection string to username and then copy encrypted string to connection string column in database.
Just check below example I have written and invented this trick. Thank you.
# Code By SB 2019
$ReportServerURI = 'http://localhost/PowerBIReports' # Input Local path of powerbi file
$filePath = "C:\12.pbix" # Input Local path of powerbi file
$PBIxfileName = "12" # INput your Powerbi File Name
$FolderName ='NewDataset' # Input PowerBI server Folder Name Where you wann to deploy
$Username ='admin'
$password ='password'
$ReportServerName ='localhost\SQl2017' #input SQL server where POWERBI database installed
$ReportServerDatabase = 'ReportServerPowerBI' #input PowerBi Database Name
$ConnectionString ='data source=Client01\SQL2019;initial catalog=Client_SB_1' # input New Connection String / Client ConnectionString
$FolderLocation = '/'
$FolderPath = $FolderLocation + $FolderName
write-host "Deployment Started ..." -ForeGroundColor Yellow
$session = New-RsRestSession -ReportPortalUri $ReportServerURI
Write-RsRestCatalogItem -WebSession $session -Path $filePath -RsFolder $folderPath -Description $Description -Overwrite
$datasources = Get-RsRestItemDataSource -WebSession $session -RsItem "$FolderPath/$PBIxfileName"
$dataSources[0].DataModelDataSource.AuthType = ‘Windows'
$dataSources[0].DataModelDataSource.Username = $ConnectionString
$dataSources[0].DataModelDataSource.Secret = $password
Set-RsRestItemDataSource -WebSession $session -RsItem "$folderPath/$PBIxfileName" -RsItemType PowerBIReport -DataSources $datasources
$ID = $dataSources[0].Id
$Query = " Update [DataModelDataSource] SET ConnectionString = Username From [dbo].[DataModelDataSource] Where DataSourceID ='" + $ID + "' "
Invoke-Sqlcmd -Query $Query -ServerInstance CPMSUNRSQL17\CPMSRINST17 -Database ReportServerPowerBI
$datasources = Get-RsRestItemDataSource -WebSession $session -RsItem "$FolderPath/$PBIxfileName"
$dataSources[0].DataModelDataSource.Username = $Username
$dataSources[0].DataModelDataSource.Secret = $password
Set-RsRestItemDataSource -WebSession $session -RsItem "$folderPath/$PBIxfileName" -RsItemType PowerBIReport -DataSources $datasources
write-host "Deployment Done . . ." -ForeGroundColor Green
This would only work if the change you need can be driven by a parameter, e.g. for a SQL Server source, can set database, schema or table name (but not server name).
First I would set up the query definitions to use query parameter(s) and test. The specifics of this would depend on your data sources and scenario - you have not provided any info on that.
Then I would call the appropriate REST API Update Parameters method - probably the Group version.
https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/updateparametersingroup
You can deploy using to Power BI Report Server, and change connections and other setting using Powershell using the ReportingServiceTools library, As Power BI Report Service is SSRS you can use the same tools, to load reports, change data connections etc
Example of deploying a file and here
You can also change the connection settings directly in the PBIX file. If you change the extension from pbix to zip you can take a look inside.
If you open the 'Connections' file, it contains the setting via a JSON structured file
{"Version":1,"Connections":[{"Name":"EntityDataSource","ConnectionString":"Data Source=asazure://region.asazure.windows.net/somecubegoes her;Initial Catalog=SmartSpacesAnalysis;Cube=SmartSpacesModel","ConnectionType":"analysisServicesDatabaseLive"}]}
That can be read and changed if needed

Automating configuration of SQL Server 2017 Reporting Services

I am trying to silently install and configure SQL Server 2017 Reporting Services. The silent install is straightforward, and I have most of the configuration done, using the PowerShell script below.
Where I run into an issue is when attempting to set the virtual directory for the Report Manager. I receive an error on the following line
$configset.SetVirtualDirectory("ReportManager", "Reports", 1033)
HRESULT -2147220938: The application is not found.
Per How to automate SSRS install and configuration, it appears I am performing the steps in the correct order.
$configset = Get-WmiObject –namespace "root\Microsoft\SqlServer\ReportServer\RS_SSRS\v14\Admin" `
-class MSReportServer_ConfigurationSetting -ComputerName localhost
$configset
If (! $configset.IsInitialized)
{
[string]$dbscript = $configset.GenerateDatabaseCreationScript("ReportServer", 1033, $false).Script
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force
Import-Module sqlps -DisableNameChecking | Out-Null
$conn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection -ArgumentList $env:ComputerName
$conn.ApplicationName = "Script"
$conn.StatementTimeout = 0
$conn.Connect()
$smo = New-Object Microsoft.SqlServer.Management.Smo.Server -ArgumentList $conn
# Create the ReportServer and ReportServerTempDB databases
$db = $smo.Databases["master"]
$db.ExecuteNonQuery($dbscript)
# Set permissions for the databases
$dbscript = $configset.GenerateDatabaseRightsScript($configset.WindowsServiceIdentityConfigured, "ReportServer", $false, $true).Script
$db.ExecuteNonQuery($dbscript)
# Set the database connection info
$configset.SetDatabaseConnection("(local)", "ReportServer", 2, "", "")
$configset.SetVirtualDirectory("ReportServerWebService", "ReportServer", 1033)
$configset.ReserveURL("ReportServerWebService", "http://+:80", 1033)
$configset.SetVirtualDirectory("ReportManager", "Reports", 1033)
$configset.ReserveURL("ReportManager", "http://+:80", 1033)
$configset.InitializeReportServer($configset.InstallationID)
$configset.IsReportManagerEnabled
$configset.IsInitialized
$configset.IsWebServiceEnabled
$configset.IsWindowsServiceEnabled
$configset.ListReportServersInDatabase()
$configset.ListReservedUrls();
$inst = Get-WmiObject –namespace "root\Microsoft\SqlServer\ReportServer\RS_SSRS\v14" `
-class MSReportServer_Instance -ComputerName localhost
$inst.GetReportServerUrls()
}
Any insights into this issue are appreciated!
The issue was the with SQL Server 2016 (and later), the name of the web application for the report manager has changed from ReportManager to ReportServerWebApp.
You could use DSC this link should have information on how to use the dsc resources:
https://learn.microsoft.com/en-us/sql/database-engine/install-windows/install-sql-server-on-server-core
When this code was Xrev I was able to install and configure SSRS using a resource at that time called MSFT_xSQLServerSetup.
Here is an example of setting up a single sql server. https://github.com/PowerShell/SqlServerDsc/blob/master/Examples/SQL-Standalone.ps1

Powershell "screen" - keep the processes running even the connection is dropped?

I'm using enter-pssession to run scripts on remote servers. So I can login remotely to the servers. Run commands interactively, close the powershell console and later I can reattach the session and check the commands outputs.
Is there a Linux screen like functionality in powershell? I cannot use Windows remote desktop to connect the servers.
You can use Invoke-Command with -InDisconnectedSession, it will start session in asynchronous mode. After you can connect to this session, take data from it, etc. You can read more about this here.
You can create session, disconnect from session, connect back to it.
May be useful for you: New-PSSessionOption with -IdleTimeout.
-IdleTimeout:
Determines how long the session stays open if the remote computer does not receive any communication from the local computer. This includes the heartbeat signal. When the interval expires, the session closes. MSDN Link
I have recently run into double-hop issues with using PSSessions. What I did to work around that is to create a Session Configuration on the remote server that uses the -RunAs parameter to set the credentials that I need the commands on the remote server to be executed as. Then you connect to that session configuration on the remote server, and things should work as expected.
$MyCreds = Get-Credential ''
Invoke-Command -ScriptBlock {
Set-PSSessionConfiguration -Name "My Remote Config" -RunAsCredential $using:MyCreds -Force
} -ComputerName Server01
Then once the session configuration exists I can start a session using that config, and the whole double hop issue is null and void.
Now, mind you I do add some additional security, so that other people cannot use my session config, since that config has my credentials cached on the server (encrypted), and if they used that config they could do whatever they wanted as me. So to accomplish that I get my domain account SID, generate a SDDL line, and restrict access to the Session Config to only my account.
$Searcher = [adsisearcher]"(&(sAMAccountName=$($Creds.UserName.Split('\')[1]))(objectClass=user))"
$Results=$Searcher.FindOne().GetDirectoryEntry()
$MySID = new-object System.Security.Principal.SecurityIdentifier($Results.objectSid.value,0)|% value
$SDDL = "O:NSG:BAD:P(A;;GR;;;BA)(A;;GR;;;IU)(A;;GA;;;$MySID)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)"
$FQDN = $Server.ServerName,$Server.Forest -join '.'
$MySessionName = "DoubleHop-{0}" -f $MyCreds.UserName.Split('\')[1]
Invoke-Command -ScriptBlock {
Register-PSSessionConfiguration -Name $using:MySessionName -RunAsCredential $using:MyCreds -Force -SecurityDescriptorSddl $using:SDDL
} -ComputerName $FQDN -ea 4

How to run Powershell script on local computer but with credentials of a domain user

I have to implement a solution where I have to deploy a SSIS project (xy.ispac) from one machine to another. So far I've managed to copy-cut-paste the following stuff from all around the internet:
# Variables
$ServerName = "target"
$SSISCatalog = "SSISDB" # sort of constant
$CatalogPwd = "catalog_password"
$ProjectFilePath = "D:\Projects_to_depoly\Project_1.ispac"
$ProjectName = "Project_name"
$FolderName = "Data_collector"
# Load the IntegrationServices Assembly
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices")
# Store the IntegrationServices Assembly namespace to avoid typing it every time
$ISNamespace = "Microsoft.SqlServer.Management.IntegrationServices"
Write-Host "Connecting to server ..."
# Create a connection to the server
$sqlConnectionString = "Data Source=$ServerName;Initial Catalog=master;Integrated Security=SSPI;"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString
$integrationServices = New-Object "$ISNamespace.IntegrationServices" $sqlConnection
$catalog = $integrationServices.Catalogs[$SSISCatalog]
# Create the Integration Services object if it does not exist
if (!$catalog) {
# Provision a new SSIS Catalog
Write-Host "Creating SSIS Catalog ..."
$catalog = New-Object "$ISNamespace.Catalog" ($integrationServices, $SSISCatalog, $CatalogPwd)
$catalog.Create()
}
$folder = $catalog.Folders[$FolderName]
if (!$folder)
{
#Create a folder in SSISDB
Write-Host "Creating Folder ..."
$folder = New-Object "$ISNamespace.CatalogFolder" ($catalog, $FolderName, $FolderName)
$folder.Create()
}
# Read the project file, and deploy it to the folder
Write-Host "Deploying Project ..."
[byte[]] $projectFile = [System.IO.File]::ReadAllBytes($ProjectFilePath)
$folder.DeployProject($ProjectName, $projectFile)
This seemed to be working surprisingly well on the development machine - test server pair. However, the live environment will be a bit different, the machine doing the deployment job (deployment server, or DS from now on) and the SQL Server (DB for short) the project is to be deployed are in different domains and since SSIS requires windows authentication, I'm going to need to run the above code locally on DS but using credentials of a user on the DB.
And that's the point where I fail. The only thing that worked is to start the Powershell command line interface using runas /netonly /user:thatdomain\anuserthere powershell, enter the password, and paste the script unaltered into it. Alas, this is not an option, since there's no way to pass the password to runas (at least once with /savecred) and user interactivity is not possible anyway (the whole thing has to be automated).
I've tried the following:
Simply unning the script on DS, the line $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString would use the credentials from DS which is not recognized by DB, and New-Object does not have a -Credential arg that I could pass to
Putting everything into an Invoke-Command with -Credential requires using -Computername as well. I guess it would be possible to use the local as 'remote' (using . as Computername) but it still complains about access being denied. I'm scanning through about_Remote_Troubleshooting, so far without any success.
Any hints on how to overcome this issue?
A solution might be to use a sql user (with the right access rights) instead of an AD used.
Something like this should work.
(Check also the answer to correct the connection string)

Trust relationship auto fix script

i am trying to come up with a script to automate the fix for the common issue in domain environment "the trust relationship error " for my help-desk employee , where they can just run the script with required variable
options : using power-shell or PsExec and should accept user input for naive user .
looking at powershell a simple line may fix the issue after google research : " Test-COmputerSecureChannel -Repair " which does not require reboot as well
challenges in powershell per my simple knowledge ( remote command execution should be enabled in remote machine which is not an option
> PsExec not available by default windows 7 / citrix employee
computer name : SAWD456335355 ( should be variable - user input )
local admin : Administrator
local password: variable differ from computer to computer ( should be user input as well accept special character )
=================================
Privilege admin level 1 account for pop up
while trying to change the local computer using team viewer a pop up will ask for domain credentials for instance :
user name would be sth like : admingroup1
password for privlege admin : password#123 < for example
There are three ways you could fix this.
What you are actually asking for, repair the secure channel. You will most likely need a local admin account (local because the trust relationship is broken) and a combination of Psexec and PowerShell remoting.
<# Get Help desk operator input#>
$Computer = Read-Host "Enter Computer name"
$AdminAccount = Read-Host "Enter local Admin Account"
$SecurePassword = Read-Host "Enter local Admin Password" -AsSecureString
<# Create Plain text password object and Credential Object#>
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $AdminAccount, $SecurePassword
<#Enable PS Remoting#>
Psexec.exe \$Computer -u $AdminAccount -p $UnsecurePassword -h -d powershell.exe "enable-psremoting -force"
<# Repair secure Channel#>
Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock {
Test-ComputerSecureChannel -Repair
}
Set the domain to NOT reset domain computer accounts. This is probably not recommended in most environments.
In my environment I found the best solution was to prevent automatic system restore (probably after a power outage or similar) that is older than the computer password as discussed here:
https://support.microsoft.com/en-us/kb/295049
My solution was to run a scheduled task to delete system restore points that are older than the current computer password.
Get-ComputerRestorePoint |`
Where {$_.ConvertToDateTime($_.CreationTime) -lt $PasswordLastSet} | `
Delete-ComputerRestorePoints
If no system restore points are left the script creates a new one.
A detailed write up can be found here:
http://blog.buktenica.com/issues-with-domain-membership-after-system-restore/