data refresh enable in cloudapp - sql

Hi im trying to make a power shell script that can automate the enable for the data refresh schedule. can anyone help me with that?
$rs2010 = New-WebServiceProxy -Uri "URL HERE" -Namespace
SSRS.ReportingService2010 -UseDefaultCredential;
$rs2010.Timeout = 3600000
$schedules = $rs2010.ListSchedules("URL HERE");
Write-Host "--- Disabled Schedules ---";
Write-Host "----------------------------------- ";
$schedules | WHERE { $_.ScheduleStatename -ne 'Ready' }
**strong text**
i have this that can output disabled schedules. i need help to make a powershell script that can enable the data refresh whenever its turn off.
/Adel
EDIT:::
so i got this code
$rs2010 = New-WebServiceProxy -Uri
"http://url here/_vti_bin/ReportServer/ReportService2010.asmx"
-Namespace SSRS.ReportingService2010 -UseDefaultCredential;
$subscription = $rs2010.ListSubscriptions("http://url here/")
| Where-Object {$_.ScheduleStatename -ne "Ready" } ;
ForEach ($subscription in $subscriptions)
{
$rs2010.EnableDatasource($subscription.SubscriptionID);
$subscription | select subscriptionid, report, path
}
but i get this error
Exception calling "EnableDataSource" with "1" argument(s): "The path of the item 'bda17ed4-81a5-40a6-bade-894ecde02373' is not valid. The full path must be less than 260 characters long;
other restrictions apply. If the report server is in native mode, the path must start with slash. ---> Microsoft.ReportingServices.Diagnostics.Utilities.InvalidItemPathException:

Related

Error Trapping of Redundant Event in 4 minute Window with PowerSell

I have a script that successfully traps an application event using a SQL query in the database. If found - it will write to the event log and sent an email to support team. Now the team wants to have a double check within a four minute window. You may get ErrorA & ErrorD twice - and ErrorB & ErrorC do not reoccur.
How would you do an internal check within the 1st loop. So first time you have ErrorA.1st and second check two minutes later you see ErrorA.1st = ErrorA.2nd, therefore send off a email?
while($true) ### Endless loop - continuely looking for ERRORS to trap for two actions below (Write event log and send email)
{
$connString = "data source=sqlservername,1433;Initial catalog=HugsDB;Integrated Security=True;"
$date= $((get-date).AddSeconds(-120).ToString("MM-dd-yyyy HH:mm:ss"))
$QueryText = "select statement that graps all errors $date"
#SETUP SQL VALUES####
$SqlConnection = new-object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $connString
$SqlCommand = $SqlConnection.CreateCommand()
$SqlCommand.CommandText = $QueryText
#### query the database
$DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
$dataset = new-object System.Data.Dataset
$rowCount = $DataAdapter.Fill($dataset)
$sqlConnection.Close()
$sqlConnection.Dispose()
#### IF QUERY FINDS ERRORS # exact time of query ( could be 1 or more devices reporting an error ) write an event log message & send team an email
if($rowCount -gt 0) {
### assign a unique variable to each unique error on 1st find.
ForEach ($row in $dataset.Tables[0].Rows) {
[int]$incre = 0
$row.exciter_name = $incre.$row.exciter_name
}
## sleep 2 minutes before checking to see if we have a repeat of any of the finds in second query
Start-Sleep -Seconds 120
## Another query used to see if a reoccurance of same error.
## If the same error occurs send email and write error to event log.
if($rowCount -gt 0) {
ForEach ($row in $dataset.Tables[0].Rows) {
## NOT SURE HOW TO DO A CHECK TO LOOK FOR REOCCURANCE TO GENERATE EVENT.
write-Eventlog -LogName Exciter_Log -Source Exciter_Health –EventID 108 -Message "PACE Exciter Health Alert"
Send-MailMessage -smtpserver "$SMTPServer" -from "$EmailFrom" -to "$EmailTo" -subject "$Subject" -bodyAsHtml "$Body" -credential $anonCredentials
#################################################################################################################################################
#Second BREAK
Start-Sleep -Seconds 120
}
Sounds like you need to keep track of your previous message and compare them with the new messages. I'm assuming from the code that it does not matter which error message is actually repeated, but only that one is. In the example below what I've done is capture all unique messages in a variable called $currentErrors. Once done with capturing the messages you'll want to check if any of these previous errors appear in in this current set. If even one repeat error is found the the $alert flag is set to true and performs your error handling. Last it moves all current error messages into previous error message to be checked on the next run.
$currentErrors = #()
$alert = $false
if ($rowCount -gt 0)
{
foreach ($row in $dataset.Tables[0].Rows)
{
# not sure what these 2 lines do?
[int]$incre = 0
$row.exciter_name = $incre.$row.exciter_name
if ($currentErrors -notcontains $row.exciter_name) { $currentErrors += $row.exciter_name } # add error message to $currentErrors if not already added
}
# on first run previousErrors will be null so this foreach will do nothing
foreach ($error in $previousErrors)
{
if ($currentErrors -contains $error)
{
# previous error found in current errors
$alert = $true
break # exit loop once duplicate error is found
}
}
if ($alert)
{
Write-EventLog -LogName Exciter_Log -Source Exciter_Health –EventID 108 -Message "PACE Exciter Health Alert"
Send-MailMessage -smtpserver "$SMTPServer" -from "$EmailFrom" -to "$EmailTo" -subject "$Subject" -bodyAsHtml "$Body" -credential $anonCredentials
}
# move currentErrors into previousErrors for next loop
$previousErrors = $currentErrors
Start-Sleep -Seconds 120
}

Why does the array stop storing when an error happens?

I have been working on the following code that supposedly retrieves all powerbi reports from the server, checks if they have refresh plans, if they dont, it outputs "No refresh pans exist..", and if it does have it, then it outputs refreshplan info like description.
$webPortalURL = "https://server-pbi.domain.com/reports"
$PBI_Reports_Array = #()
$PBI_Reports_Array = $(Invoke-RestMethod -UseDefaultCredentials -uri $($webPortalURL + "/api/v2.0/PowerBIReports"))
$loopCount = 0
$refreshPlanArray = #()
foreach ($reportPath in $PBI_Reports_Array.value.path) {
$refreshPlanArray += $(Invoke-RestMethod -UseDefaultCredentials -uri $($webPortalURL + "/api/v2.0/PowerBIReports(path='" + $reportPath + "')/CacheRefreshPlans"));
write-host "$($refreshPlanArray[$loopCount])" -foregroundcolor magenta; #testing output here to debug
if ([string]::IsNullOrEmpty($($refreshPlanArray[$loopCount].value))) {
write-host "$loopCount | $reportPath | No Refresh Plan Exists for this report!";
}
else {
write-host "$loopCount | $reportPath | $($refreshPlanArray[$loopCount].value.Description) | $($refreshPlanArray[$loopCount].value.ScheduleDescription)" -foregroundcolor magenta;
}
$loopCount++;
}
i am running into a weird bug. so i have 2 servers/portals, on one of the servers/portals, when i run this script, it retrieves all reports and does exactly what i am expecting it do as described above.
when i thought i finished developing the script, i tested it on production portal/server and it wasnt working as expected!
i debugged for many hours until i think i found whats happening, but idk what to do about it:
basically, the reason why it worked on one server/portal but not the other is because the nonproduction portal/server didnt have this error:
Invoke-RestMethod : The remote server returned an error: (404) Not Found.
apparently, before that error happened on the production server/portal where this failed, this line write-host "$($refreshPlanArray[$loopCount])" i added for debugging purposes was printing the following odata contexts up until the error happened!
#{#odata.context=https://server-pbi.domain.com/reports/api/v2.0/$metadata#CacheRefreshPlans; value=System.Object[]}
then when the error occurred after iteration 4, it stopped printing the odata!
why is that?
I figured it out!
$loopCount is the culprit! it has to be inside a try, or the "good" part of the code, otherwise, the array indexing gets messed up with the 404 NULL value
This is the correct code:
$webPortalURL = "https://server-pbi.domain.com/reports"
$PBI_Reports_Array = #()
$PBI_Reports_Array = $(Invoke-RestMethod -UseDefaultCredentials -uri $($webPortalURL + "/api/v2.0/PowerBIReports"))
$loopCount = 0
$refreshPlanArray = #()
foreach ($reportPath in $PBI_Reports_Array.value.path) {
try {
$refreshPlanArray += $(Invoke-RestMethod -UseDefaultCredentials -uri $($webPortalURL + "/api/v2.0/PowerBIReports(path='" + $reportPath + "')/CacheRefreshPlans"));
if ([string]::IsNullOrEmpty($($refreshPlanArray[$loopCount].value))) {
write-host "$loopCount | $reportPath | No Refresh Plan Exists for this report!";
}
else {
write-host "$loopCount | $reportPath | $($refreshPlanArray[$loopCount].value.Description) | $($refreshPlanArray[$loopCount].value.ScheduleDescription)" -foregroundcolor magenta;
}
$loopCount++;
}
catch {
}
}

How to do a web request call to sqlpad?

Hi I have been trying to do a web request call to sqlpad.
I have got the basis of the script to make the connection
Invoke-WebRequest -uri
However when I run the command I get connection 200 showing it has made a connection but how do I use cached cookies or how do I sign into sqlpad using credentials and run query all from using web request.
Sorry I am new to powershell and webrequest so I appreciate all your advice thank you.
That should be doable. You'd need to use sqlpad api. To keep cookies you need to create a session variable when calling signin and reuse it in later calls. To extract query data you'd need to use query-result end point. You need to know connectionId (can lookup at api/connections using browser) and SQL code (query text). Turns out there is no direct way to run query by query name. So you either need to know the sql of the query or you can extract it from /api/queries for specific query
$baseUrl = "http://localhost:39325/api"
$user = "yourEmail"
$password = "yourPassword"
$signinUrl = "$baseUrl/signin?email=$user&password=$password&redirect=false"
# sign in and create session variable $ws
if(!$ws) { $r = Invoke-WebRequest -Uri $signinUrl -SessionVariable ws -Method Post } else { Write-Host "connected"}
# list of available queries and connections. May need to run this to determine connection id or existing query sql
$QueryList = Invoke-RestMethod -Uri "$baseUrl/queries" -WebSession $ws
$ConnectionList = Invoke-RestMethod -Uri "$baseUrl/connections" -WebSession $ws
Write-Host "Available queries:"
$QueryList.queries | select name, connectionId, queryText | ft -AutoSize
# Execute Query
$params = #{
connectionId = "vhsNXMXCJeI9QlUL" #use $ConnectionList var or just look up on http://localhost:39325/api/connections/
cacheKey = "null" #just some dummy value, parameter is required but it's not really affecting anything
queryName = "test2" #optional
queryText = "select top 15 * from sys.columns" # required
} | ConvertTo-Json
$head = #{'Content-Type'='application/json'}
$data = Invoke-RestMethod -Uri "$baseUrl/query-result" -Method Post -Body $params -Headers $head -WebSession $ws
$data.queryResult.rows | ft

DSC Script Resource - executes .exe, but doesn't wait until completion

Question)
How do I get a DSC script resource to wait until the code has completed before moving on?
(The code is invoke-expression "path\file.exe")
Details)
I am using powershell version 5
and am trying to get DSC setup to handle our sql server installations.
My manager has asked me to use the out of the box DSC components.
i.e. no downloading of custom modules which may help.
I have built up the config file that handles the base server build - everything is good.
The script resource that installs sql server is good.
It executes, and waits until it has installed completely, before moving on.
When I get up to the script resource that installs the sql server cumulative update, I have issues.
The executable gets called and it starts installing (it should take 10-15 minutes), but the dsc configuration doesn't wait until it has installed, and moves on after a second.
This means that the DependsOn for future steps, gets called, before the installation is complete.
How can I make the script resource wait until it has finished?
Have you tried the keyword "DependsOn" like that ?
Script MyNewSvc
{
GetScript = {
$SvcName = 'MyNewSvc'
$Results = #{}
$Results['svc'] = Get-Service $SvcName
$Results
}
SetScript = {
$SvcName = 'MyNewSvc'
setup.exe /param
while((Get-Service $SvcName).Status -ne "Running"){ Start-Sleep 10 }
}
TestScript = {
$SvcName = 'MyNewSvc'
$SvcLog = 'c:\svc.log'
If (condition) { #like a a running svc or a log file
$True
}
Else {
$False
}
}
}
WindowsFeature Feature
{
Name = "Web-Server"
Ensure = "Present"
DependsOn = "[Script]MyNewSvc"
}
Invoke-Expression doesn't seem to wait until the process has finished - try this in a generic PowerShell console and you'll see the command returns before you close notepad:
Invoke-Expression -Command "notepad.exe";
You can use Start-Process instead:
Start-Process -FilePath "notepad.exe" -Wait -NoNewWindow;
And if you want to check the exit code you can do this:
$process = Start-Process -FilePath "notepad.exe" -Wait -NoNewWindow -PassThru;
$exitcode = $process.ExitCode;
if( $exitcode -ne 0 )
{
# handle errors here
}
Finally, to use command line arguments:
$process = Start-Process -FilePath "setup.exe" -ArgumentList #("/param1", "/param2") -Wait -PassThru;
$exitcode = $process.ExitCode;

powershell v2 - how to get process ID

I have an Application, that runs multiple instances of itself. e.g
AppName.exe instance1
AppName.exe instance2
AppName.exe instance3
Using Powershell v2 I am trying to create a simple script that given an array of AppNames and instances, it loops through them, checks if they are running, and then shuts them down.
I figured the best way to do this would be check for each instance, if found capture it's processID, and pass that to the stop-process cmdlet.
BUT, I can't figure out how to get the process id.
So far I have:
$appName = "AppName.exe"
$instance = "instance1"
$filter = "name like '%"+$appName+"%'"
$result = Get-WmiObject win32_process -Filter $filter
foreach($process in $result )
{
$desc = $process.Description
$commArr = $process.CommandLine -split"( )"
$inst = $commArr[2]
$procID = "GET PROCESS ID HERE"
if($inst -eq $instance)
{
Stop-Process $procID
}
}
Can anyone tell me where to get the process ID from please?
you can use the get-process cmdlet instead of using wmi :
$procid=get-process appname |select -expand id
$procid=(get-process appname).id
When using Get-WmiObject win32_process ..., the objects returned have an attribute named ProcessId.
So, in the question, where you have:
$procID = "GET PROCESS ID HERE"
use:
$procID = $process.ProcessId
You could also use that in the $filter assignment, e.g.
$filter = "ProcessId=1234"