How to test authentication to remote IP address - authentication

I have one powershell script that invokes another powershell script.
The first script is invoked with an ip address, which gets passed to the second script. The second script is supposed to return the userId in form Domain\User
The first script uses ProcessStartInfo and Process to get elevated credentials to call the second script
# part of first script
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = "powershell.exe"
$startInfo.Arguments = "C:\script\second_script.ps1 "
$startInfo.RedirectStandardOutput = $true
$startInfo.UseShellExecute = $false
$startInfo.CreateNoWindow = $false
$startInfo.Username = Service_Account
$startInfo.Domain = Domain
$startInfo.Password = password
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$process.Start() | Out-Null
$standardOut = $process.StandardOutput.ReadToEnd()
$process.WaitForExit()
The second script has many try-catch blocks, such as checking whether we can ping the machine, checking whether we can access WMI
# part of second
# Can we ping the machine?
try{
Test-Connection $Sender_IP -count 1 -ErrorAction Stop | out-null
}
catch [Exception]
{
$userId = "Unknown/CannotPing "
return $output = "userId=" + $userId
}
try
{
<#Gather information on the computer corresponding to $Sender_IP#>
$Win32OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Sender_IP -ErrorAction Stop
}
catch [Exception]
{
$userId = "Unknown/CannotDetectOS "
return $output = "userId=" + $userId
}
The script was unable to access WMI of many IP addresses. And when I was trying to troubleshoot by manually remoting into the IP address with the service account, I was unable to.
Now, I am trying to figure out a way for the script to check whether it can authenticate to the IP address. If the script is unable to authenticate to the IP address, it should throw and exception and not even check whether it can access WMI.
What cmdlets can help with this?

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
}

data refresh enable in cloudapp

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:

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"

How to make the website Ping ARR server and say I am going down?

I have successfully configured the ARR in Windows Azure environment, the web server instances are added to server farm.
Using Health Check option in server farm, instance that timed-out or not responding is made unhealthy.
My Question is
Instead of the ARR web farm (doing health check every 10 seconds) ping the website, is it possible or the web role itself ping back the ARR server and say I am going down ?
Is it possible to ping the ARR Server from web role and say I am going down? or this is there any best approach available.
Please suggest.
I wanted some extra notifications with our ARR setup and I put this PowerShell script together that runs once an hour and checks the health status and notify me via email when ever any hosting server was seen as unhealthy. We also use other outside resources that ping the web farm externally once an minute and alerts us when it can't be seen (Pingdom). I have a feeling you're looking for a little more than this but I hope it helps a little.
#----- First add a reference to the MWA dll ----#
$dll=[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
#----- Get the manager and config object ----#
$mgr = new-object Microsoft.Web.Administration.ServerManager
$conf = $mgr.GetApplicationHostConfiguration()
#----- Get the webFarms section ----#
$section = $conf.GetSection("webFarms")
$webFarms = $section.GetCollection()
#----- Define an array for html fragments ----#
$fragments=#()
#----- Check each webfarm ----#
foreach ($webFarm in $webFarms)
{
$Name= $webFarm.GetAttributeValue("name");
#Get the servers in the farm
$servers = $webFarm.GetCollection()
#Write-Host "Farm Name: " $Name
$fragments+= "<b>Farm Name: $Name</b>"
$fragments+="<br>"
foreach($server in $servers)
{
$ip= $server.GetAttributeValue("address")
$hostname= ([system.net.dns]::GetHostByAddress($ip)).hostname
#Get the ARR section
$arr = $server.GetChildElement("applicationRequestRouting")
$counters = $arr.GetChildElement("counters")
$isHealthy=$counters.GetAttributeValue("isHealthy")
$state= $counters.GetAttributeValue("state")
switch ($state)
{
0 {$state= "Available"}
1 {$state= "Drain"}
2 {$state= "Unavailable"}
default {$state= "Non determinato"}
}
if( $isHealthy)
{
$isHealthy="Healthy"
$fragments+="$hostname -- $ip -- $state -- $isHealthy"
$fragments+="<br>"
}
else
{
$isHealthy="Not Healthy"
$notHealthy="RED ALERT!! This is what we trained for!"
$fragments+="$hostname -- $ip -- $state -- $isHealthy"
$fragments+="<br>"
}
#Write-Host -NoNewLine $hostname " " $ip " " $state " " $isHealthy
#NEW LINE
#Write-Host
}
#NEW LINE
#Write-Host
if($notHealthy){
#write the results to HTML formated email
$smtpServer = "SMTP server"
$smtpFrom = "email address"
$smtpTo = "email address"
$messageSubject = "Unhealthy Web Server"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = $fragments
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)
}
}

PowerShell RoboCopy path issue

Objective: Robo copy from multiple machines on the network to a network share using variables for both the machine name and the currently logged on user.
What I have: txt file with a list of computernames.
Issue: I cannot get the foreach to work with the .split("\")[1] I use on the username variable to remove the domain prefix so I can use the output from that in the robocopy path
something like
robocopy "\\$computername\c$\documents and settings\$username\backup" "\\networkshare\backup\$username\backup"
gives me the error
You cannot call a method on a null-valued expression.
At C:\Scripts\Test\backup.ps1:13 char:2
Here's what I have so far. Can somebody help please?
function Get-LoggedIn {
[CmdletBinding()]
param (
[Parameter(Mandatory=$True)]
[string[]]$computername
)
foreach ($pc in $computername){
$logged_in = (gwmi win32_computersystem -COMPUTER $pc).username
$name = $logged_in.split("\")[1]
"{1}" -f $pc,$name
}
}
$computers = Get-Content "C:\Scripts\testcomputers.txt"
foreach ($computer in $computers) {
$users = Get-LoggedIn $computer
}
$SourceFolder = "\\$computer\c$\users\$users\desktop"
$DestinationFolder = "\\networkshare\backups\$users\backup\desktop"
$Logfile = "\\networkshare\backups\$users\backup\backuplog.txt"
Robocopy $SourceFolder $DestinationFolder /E /R:1 /W:1 /LOG:$Logfile
I see multiple errors here. You're not running the copy commands inside the foreach-loop. The username property recieved from WMI can often be in the following format:
domain\computer\username (or computer\domain\username, unsure since I'm on non-domain workstation now)
Anyways, the username is always the last part, so get it by using the index [-1] instead.
Updated script (with indents!):
function Get-LoggedIn {
[CmdletBinding()]
param (
[Parameter(Mandatory=$True)]
[string[]]$computername
)
foreach ($pc in $computername){
$logged_in = (gwmi win32_computersystem -COMPUTER $pc).username
$name = $logged_in.split("\")[-1]
"{1}" -f $pc,$name
}
}
$computers = Get-Content "C:\Scripts\testcomputers.txt"
foreach ($computer in $computers) {
$users = Get-LoggedIn $computer
$SourceFolder = "\\$computer\c$\users\$users\desktop"
$DestinationFolder = "\\networkshare\backups\$users\backup\desktop"
$Logfile = "\\networkshare\backups\$users\backup\backuplog.txt"
& Robocopy $SourceFolder $DestinationFolder /E /R:1 /W:1 /LOG:$Logfile
}