Sunday, October 26, 2014

Check, enable, disable ssh (Start/Stop Service) on esxi using powercli

Troubleshooting esxi issues using vmkernel and other logs is daily task of vsphere administrator. for this SSH service should be running on esxi server so esxi server can be connected through putty, and in the end of the day if you have company policy in place where they says SSH service should be disable after work is done (I have seen in ICINGA or Nagios monitoring tools if SSH services is enabled it throws alert). It is time consuming when you want to check and stop ssh service on esxi server.  

Here this script is handy check the status of SSH service and get report.
 

Check Status of service
Get-VMHost | Get-VMHostService | Where-Object {$_.Key -eq 'TSM-SSH'} | Select-Object -Property VMHost, Key, Label, Policy, Running
 

Check Status of SSH firewall rule it also shows status of service running or not
Get-VMHost | Get-VMHostFirewallException | Where-Object {$_.Name -eq "SSH Server"} | Select-Object VMHost, Name, Enabled, IncomingPorts, OutgoingPorts, TCP, ServiceRunning


Where running column shows what is the current state of service whether it is running false or true. Another state is policy, there are 3 options to this on, off, automatic.

Policy - on: (Start and stop with host): Starts and stops the SSH service when the host powers on or shuts down.
Policy - off: (Start and stop manually): Enables manual starting and stopping of the SSH service.

Policy - Automatic: (Start and stop with port usage): Starts or stops the SSH service when the SSH client port is enabled or disabled for access in the security profile of the host.


How to start (enable) SSH service on esxi hosts
before running this script you will need to connect to vcenter or esxi host through powercli before running this script, and once this script executed, you can simply run below cmdlet in the last to start services (you can use this function in your script)
Get-VMHost | Start-SSHService

 function Start-SSHService {  
   [CmdletBinding()]  
  #####################################   
  ## http://kunaludapi.blogspot.com   
  ## Version: 1   
  ## Tested this script on successfully  
  ## 1) Powershell v3   
  ## 2) Windows 7
  ## 3) vSphere 5.5 (vcenter, esxi, powercli)
  #####################################   
  Param (  
     [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)]  
     [ValidateNotNullOrEmpty()]  
     [Alias("Name")]  
     [string]$VMHost  
   )  
   begin {}  
   Process {  
     $AllServices = Get-VMHostService -VMHost $VMHost   
     $SShService = $AllServices | Where-Object {$_.Key -eq 'TSM-SSH'}   
     if ($SShService.running -eq $false) {  
       $SShService | Start-VMHostService -confirm:$false  
     }  
     else {  
       Write-Host -BackgroundColor DarkGreen -Object "SSH service on $VMHost is already running"  
     }  
   }  
   end {}  
 }  
 #Get-VMHost | Start-SSHService  

How to Stop (disable) SSH service on esxi host
Stopping service is similar to starting service. run below commands in the last once below given script or function loaded into memory.

Get-VmHost | Stop-SSHService
 function Stop-SSHService {  
  #####################################    
  ## http://kunaludapi.blogspot.com    
  ## Version: 1    
  ## Tested this script on successfully   
  ## 1) Powershell v3    
  ## 2) Windows 7  
  ## 3) vSphere 5.5 (vcenter, esxi, powercli)  
  #####################################   
   [CmdletBinding()]  
   Param (  
     [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)]  
     [ValidateNotNullOrEmpty()]  
     [Alias("Name")]  
     [string]$VMHost  
   )  
   begin {}  
   Process {  
     $AllServices = Get-VMHostService -vmhost $VMHost   
     $SShService = $AllServices | Where-Object {$_.Key -eq 'TSM-SSH'}   
     if ($SShService.running -eq $true) {  
       $SShService | Stop-VMHostService -confirm:$false  
     }  
     else {  
       Write-Host -BackgroundColor darkGreen -Object "SSH service on $VMHost is already stopped"  
     }  
   }  
   end {}  
 }  
 

While writing this script I faced some issues and it is mentioned in this KB Article
Schedule PowerShell (.PS1 file) script in Windows Task Scheduler - Part3

Saturday, October 25, 2014

Capture top memory consuming task manager processes with Powershell

One of x-colleague and good friend of mine called me and said that, recently they are receiving lots of alerts for high memory usage on their monitoring software (Windows and Linux), As they are using some old open source tool currently and it doesn't have capability to tell which process is consuming most of the memory. (It can be monitored through Performance Monitor - Perfmon under Process, This script is just created out of curiosity)

He asked me to write a script to capture top 10 memory consuming processes (for Windows servers) in CSV/XLS file format for creating fancy charts. (Another request was that He should be able to schedule it as they were receiving alerts randomly any time of day or after couple of days for few minutes only, keep watching task manager or resource monitor whole day was very time consuming process and not good for them when meeting SLAs)

below script is useful for the same conditions or can be used as general purpose tool by system administrators.

   <#  
   .SYNOPSIS  
   PowerShell function to monitor what process is using resources   
   .DESCRIPTION  
   Includes parameters to monitor server and latecy, and capture data in file.  
   .EXAMPLE  
   Monitor-ProcessMemoryUsage -IntervalinSeconds 600 -MonitorPeriodHours 1 -File c:\temp\CapturedData.csv  
   #>   
  #####################################   
  ## http://kunaludapi.blogspot.com   
  ## Version: 1   
  ## Tested this script on successfully  
  ## 1) Powershell v4   
  ## 2) Windows 7   
  ##   
  #####################################  
   [CmdletBinding()]  
     param(  
       [Parameter(Mandatory=$False, HelpMessage="Enter Interval in seconds[After how many second you want to capture data]")]  
       [alias("Interval","I")]  
       [string]$IntervalinSeconds = 300,  
       [Parameter(Mandatory=$False, HelpMessage="For how long you want to capture data [in hours]")]  
       [alias("Monitor","M")]  
       [string]$MonitorPeriodHours = 1,  
       [Parameter(Mandatory=$False, HelpMessage="Where you want to store CSV file")]  
       [alias("File","F")]  
       [string]$FileName = "$env:USERPROFILE\Desktop\$("MemUsage{0}{1}{2}.csv" -f $(Get-Date).day, $(Get-Date).Month, $(Get-Date).Year)"  
     )  
   begin {  
     $FutureTime = [DateTime]::Now.AddHours($MonitorPeriodHours)  
     $i=0  
   }  
   process {  
     do {  
       $i++  
       $TimeNow = [DateTime]::Now  
       $AllProcesses = Get-Process -IncludeUserName   
       $Processors = Get-WmiObject -Namespace root\CIMv2 -Class win32_processor | Select-Object -ExpandProperty NumberOfLogicalProcessors  
       $SortedMemory = $AllProcesses | Sort-Object PM -Descending   
       $TopMemory = $SortedMemory | Select-Object -First 10 -Property @{l="Number"; e={$i}}, @{l="Time"; e={$TimeNow}}, Name, Description, Path, Id, StartTime, @{l="Private Memory (MB)"; e={[Math]::Round($($_.PM / 1mb),2)}}, UserName  
       $TopMemory | Export-Csv -NoTypeInformation -Path $FileName -Append  
       Start-Sleep -Seconds $IntervalinSeconds  
     }   
     While ([DateTime]::Now -lt $FutureTime)  
   }  
   end {}  

How does this script works?
Get-Process is the the main cmdlet will pull the required data. You will have to copy paste script in notepad and save it as ps1 extension file. In my scenario I named it Monitor-ProcessMemoryUsage.ps1 and saved it in c:\temp folder location

Open powershell (run as administrator), change directory path to the location where ps1, script is stored 



and run the the ps1 file as above screenshot, there are some of the parameters associated (if you dont provide any parameters and just run the script with .\monitor-processmemoryusage.ps1 it will take below values by default)


-IntervalinSeconds

After how many seconds you want to monitor and store process memory usage in file., if you dont provide this value it will take 300 seconds means after every 5 min it will store data.
-MonitorPeriodHours
For how hours data will be keep collecting default value is 1 hour.
-FileName
filename and Location of csv file, by default it keep file on your desktop.

Once you received data you can manipulate it in excel and after filtering and other stuff you can pull cool Chart or graph reports.







 Schedule PowerShell (.PS1 file) script in Windows Task Scheduler - Part3

Sunday, October 5, 2014

Where is DNS and Routing settings in vsphere web Client?

Today I wanted to change DNS settings on esxi server through VMware web client, and as usual I went to esxi configuration tab, under Software panel. but boom, DNS and routing settings were missing, After checking vSphere client I was confirmed that I am trying to find out DNS and Routing under correct tab and location.



After some digging up I was able to locate it on VMware web client. Now it is under esxi server tab Manage>Networking and the name has been changed to TCP/IP stack configuration. 



Schedule PowerShell (.PS1 file) script in Windows Task Scheduler - Part 3

Back in old days I used to schedule DOS batch files a lot with windows task scheduler, same way we can schedule Powershell PS1 script. For example purpose I am using my earlier script here as a demo monitor ping latency and drops, (for parameters check the blog) I have copied script code in notepad and saved it as a PS1 extension at location c:\temp\capture-latency.ps1.

In this ps1 file in the last I added mentioned function and its parameter Computer (-c), Latency (-L), Hours (-H), Filename (F).

Open task scheduler. Right click Task Scheduler library and Create new task.



Here I have given what time this task will trigger, example 8:30 AM is a login time of all user and I want to capture details for next 30 min or 1 hours, This is the time when all users login onto Terminal Servers., and load get increased
Powershell (Program/Script) will be running with, and below parameters (Add arguments).
 

 -NoProfile -ExecutionPolicy unrestricted -File "C:\Temp\Capture-latency.ps1"

Once done and clicking on will ask for the user credentials by on what user behalf this task need to be run, you should know password for the same user.

You will see the task just you created.

After creating task it gave warning that user should be have permissions to log on as batch job, for this I added same user in Backup Operators group to ensure he will get correct rights.

As the below screenshot you can locate same settings in GPEDIT.MSC. (This is just a demo here there are other best ways to provide users this permission)

To test the job you can right click and Run it, you will see csv file generated under c:\temp\folder

You can end the task by right clicking job., and verify the CSV file, if you find it is successful, you are ready to wait for next schedule to start this job.

Powershell Ping multiple IP addresses
Capture ping Latency or drops results with powershell - Part1
Capture multiple IP Latency or drops results with powershell Test-Connection - Part 2
Schedule PowerShell (.PS1 file) script in Windows Task Scheduler - Part 3

Thursday, October 2, 2014

Powershell AD password (unique) reset and send email



Resetting passwords is a day to day task of helpdesk or IT team and it also plays crucial role in IT security, here I have written a script which can be used to reset password, unlocks it. The main thing about this script is Helpdesk/IT team is resetting password but not aware of the password. Every time they run script, it generates unique password and that can be sent to AD account owners Manager or Team Leader over email. It uses my earlier written script to generate unique random password.

On the machine you will be performing this test, must have RSAT (Remote server administration tools – AD DS tools, PowerShell Modules for AD) installed,
This is the primar, how run powershell ps1 script, Copy script content in notepad and save it on c:\temp location (you can use your own location), Rename extension to ps1.

You will need to make small modification in the script, and will have to mention “from” email ID (From this email ID managers will receive email) and “SmtpServer” (Email server) information, this one time.

Once everything is in place open Command Prompt (cmd), run as administrator.
When you run below command you are opening powershell within command prompt and executing script file, Also the execution policy is set to unrestricted so scripts will be executed.

Powershell –NoProfile –ExecutionPolicy unrestricted –File c:\temp\Reset-Account.ps1
ActiveDirectory module will get imported into powershell.


Type valid SAM AD account name (in case you are just hitting enter or wrong name it will prompt you for the same will not exit until you provide correct information, As it verifies with AD whether account is valid), next it will ask whom this email containing password should go. now ask TL to check email.

I hope this is informative and will help someone to implement AD password reset security.

 
 #####################################  
 ## http://kunaludapi.blogspot.com  
 ## Version: 1  
 ## Tested this script on successfully
 ##  1) Powershell v3  
 ##  2) Windows 2012  
 ##  
 #####################################
Begin {  
   Clear-Host  
   #Check for Active Directory module  
   if (-not (Import-Module activedirectory)) {  
     Import-Module activedirectory  
   }  
   
   #Generate Random Password  
   function Generate-Password {  
     $alphabets= "abcdefghijklmnopqstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()"  
     $char = for ($i = 0; $i -lt $alphabets.length; $i++) { $alphabets[$i] }  
   
     for ($i = 1; $i -le 9; $i++)  
     {  
       $CharArray += Write-Output $(get-random $char)  
       if ($i -eq 9) {} #write-output `n  
     }  
     $CharArray  
   }  
     
   #Get AD user account and validate it  
   do {   
     $SamAccountName = Read-Host "`nReset Password For AD Account"  
   
     if ($SamAccountName -eq "") {  
       Clear-Host  
       Write-Host -Object "`nPlease type AccountName`n" -BackgroundColor Red  
       continue  
     }  
     elseif ($(Get-ADUser -LDAPFilter "(sAMAccountName=$SamAccountName)").SamAccountName -eq $SamAccountName) {  
       $AccountToReset = Get-ADUser -LDAPFilter "(sAMAccountName=$SamAccountName)"  
         
       break  
     }  
     else {  
       Clear-Host  
       Write-Host -Object "`nTyped Account Name doesn't exists, Please try again`n" -BackgroundColor Red  
       $Everything_is_fine = $false   
     }  
   }  
   while ($SamAccountName -eq "" -or $Everything_is_fine -eq $false)  
     
   Write-Host "`nAccount has been verified and it exists`n" -ForegroundColor Green  
     
   $To = Read-Host "`nTL or Manager you want to send password to[Manager@example.com]"  
   #One Time Information fillup  
   $From = "donotreply@example.com"  
   $Subject = "Password reset request for user $SamAccountName"  
   $SmtpServer = "mail.example.com"  
   $port = 25  
 }  
   
 Process {  
   #Reset password and unlock it  
   $PlainText = Generate-Password  
   $Password = ConvertTo-SecureString -AsPlainText $PlainText -Force  
   $AccountToReset | Set-ADAccountPassword -Reset -NewPassword $Password  
   $AccountToReset | Unlock-ADAccount  
   Write-Warning "Password reseted and unlocked"  
   
   #Send Email  
   $Body = "$SamAccountName requested for New password and it is $PlainText"  
   Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port 25  
   Write-Host "Information emailed to Manager or TL" -ForegroundColor Cyan  
 }  
   
 End {  
   #Write-Host "New password is $PlainText"  
   Pause  
 }  
I am aware of System.Security.Cryptography.RNGCryptoServiceProvider for solid randomness. but wanted to build this script as a example only. Also this script compiling this to exe will help to more secure it. You can use this script and some more variations to it, example instead of sending an email, password can be sent to user over SMS. (for this User account properties should be have information).

Generate random password Powershell.