≡ Menu

A application can go unresponsive because of various reasons. Until, we identify and kill such applications, the system hands and creates log of inconvenience to the user. Such applications also consume resources and make system unstable. So, let us see how to identify the not responding applications in a computer.

When I say “Not Responding”, I mean to refer to the status that the applications shows in Task manager. Some applications look fine from task manager perspective but may not be doing their actual task. They are out of scope for this post.

Each process returned by Get-Process has a attributed called Responding which indicates the status of application. The value of this attribute is set to True if the application is running fine. A False value indicates that application is not responding.

Code:

[CmdletBinding()]            
Param(            
 [string[]]$ComputerName = $env:ComputerName            
)            

foreach($Computer in $ComputerName) {            
 if(!(Test-Connection -ComputerName $Computer -Count 1 -quiet)) {             
  Write-Host "$Computer : OFFLINE"            
  Continue            
 }            
 try {            
  $Processes = Get-Process -ComputerName $Computer -EA Stop            
  $nProcesses = @($Processes | ? { $_.Responding -eq $false })            
 } catch {            
  Write-Error "Failed to query processes. $_"            
 }            

 if($nProcesses) {            
  foreach($nProcess in $nProcesses) {            
   $nProcess | select Name, id, MainWindowTitle, Responding            
  }            

 } else {            
  Write-host "No non-responding processes found"            
 }            

}

This function will return name, PID, windows title of the non responding process. If you want to kill such processes, refer to the article I have written for 4SYSOps(http://4sysops.com/archives/query-and-kill-a-process-on-a-remote-computer-using-powershell-and-wmi/)

{ 1 comment }

Whenever a server reboot is performed, a big question comes into mind is, “All services started properly”? Let us discuss this topic a bit more in this post.

Normal approach to verify services status after server restart is looking for automatic status and their current state(start/stop). While this is good for Operating system related services, not up to the mark for any application based services. I have seen application services where the application startup is set to manual and the service is started via some scheduled task/startup task. Both in house developed applications and third party vendor applications come in this category. In some cases, I suggested the teams to use right state(automatic) to get their services started after the server reboot, but in other cases, it was a sort of dependency on the other components of the system that making developers to create such weird kind of start up procedures.

So, while checking for a more authentic way to verify a service start up status, I came across service exit codes. Each service will have exit code set when the service is attempted to start/stop. Examining these errors codes will cover all kinds of scenarios and more efficient way to check services startup status after the server reboot.

Each service will have a exit code and we can read by using WMI. Let us look at the below example.

Get-WMIObject -Class Win32_Service -Filter "Name='spooler'"
service-returncode-0

Here I am querying spooler service using WMI and the return code from this service is 0(zero). That means it started property.

Now let us look at another service which is in stopped state.

Get-WmiObject -Class Win32_Service -Filter "Name='Fax'"
service-returncode-1

The return code here is 1077. If you type net helpmsg 1077 in command prompt, you will know what is the meaning of this error.

1077-error

So, 1077 means, this service was never attempted to start so no scope of failures here.

Like this you can analyze the startup status of a service by looking at the exit codes. I wrapped my whole explanation into small powershell code for your usage. I haven’t completely tested this yet, but you know any false positives, do let me know and I will try to improve this.

Code : Get-ServicesFailedToStart.ps1

[cmdletbinding()]            
Param(            
[string[]]$ComputerName = $env:ComputerName            
)            

foreach($Computer in $ComputerName) {            
 if(Test-Connection -Computer $Computer -Count 1 -quiet) {            
  try {            
   $services = Get-WMIObject -Class Win32_Service -Filter "State='Stopped'" -ComputerName $Computer -EA stop            
   foreach($service in $services) {            
    if(!(($service.exitcode -eq 0) -or ($service.exitcode -eq 1077))) {            
     $Error = Invoke-Expression "net helpmsg $($service.Exitcode)"            
     $Service | select Name, Startmode, State, Exitcode,@{Label="Message";Expression={$Error[1]}}            
    }            
   }            
  } catch {            
   Write-Verbose "Failed to query service status. $_"            
  }            
 } else {            
  Write-Verbose "$Computer : OFFLINE"            
 }            
}

Output:

failed-tostart-services-output

You can download this script from Technet script gallery as well(http://gallery.technet.microsoft.com/Query-that-failed-to-start-01c610d4)

Hope this article helps and let me know if you have any feedback.

{ 3 comments }

Powershell : Write-Host Vs Write-Output

What is the difference between Write-Host and Write-Output??

I came across a useful article from PowerShell inventor about why you should not use Write-Host in general context unless you want to utilize specific features of it. It is a good read and worth having a peek. To output any data to console it is wiser to use Write-Output instead of Write-Host.

http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/

The output returned by Write-Output is passed to pipeline so the functions/cmdlets after the pipeline can read this for further processing. This is not possible if you use Write-Host.

let us examine this behavior with a small example.

function Send-text {            
    write-host "I am sending to console"            

}            
function Send-textwithwriteoutput {            
    write-Output "I am sending to console"            

}            

function Receive-Text {            

    process { write-Host "Received : $_" }            
}

I have three functions

  • Send-Text #sends text to console using write-host
  • Send-TextWithWriteOutput #sends text to console using write-output
  • Receive-Text #receives input from pipeline and shows it

Now look at the below output:

It is very clear from the above output that when sent text to console using write-host, it is not passed to pipeline. But when write-output is used the receive-text function parsed and displayed the value.

Its not that you should not use Write-Host but what I mean is use at the right place. For example, no other cmdlet can replace Write-host cmdlet when you want to apply colors to text you are displaying to console. So, it is wiser to use write-output as a general practice as we expect our code to make the output utilized by other functions/cmdlets.

Hope it is clear. Happy learning.

{ 0 comments }

Yesterday I have used PowerShell to build a VHD of Windows 8.1 from ISO file. My home laptop is having Windows 8.1 home edition and features set is limited. To explore the features in Windows 8.1 enterprise edition, I decided to make my laptop multi boot.

When I decided to make multi boot, I have two options. Install Windows 8.1 from ISO on my laptop or prepare a VHD windows 8.1 pre-installed and make my laptop via the VHD file (this is called native boot from VHD). Since the latter option is easy and not much changes are required for my laptop, I searched for evaluation Windows 8.1 VHD from Microsoft. But unfortunately, there is only ISO download for evaluation and no VHD available.

So I thought I need to create a VM in Hyper-V, install windows 8.1 via ISO and then use that VHD to boot my laptop. But wait, that a long process. After searching for a while I landed on a PowerShell script in TechNet Script gallery that can take ISO file as input and prepare VHD with OS installed. I felt it amazing and started downloading the script. I tried the script and in hardly 30 minutes I had my VHD ready. I added this VHD to my boot options and I have Windows 8.1 enterprise evaluation edition running on my laptop via VHD boot.

Since this is very useful, I thought I will share this with every. Using this procedure, you can built servers in lab/production environment very fast using ISO file and not relying on newsid.exe/sysprep like utilities.

Download the Windows 8.1 evaluation ISO from Microsoft site

Download Convert-WindowsImage.ps1 from TechNet Library

After downloading, run the script as shown below from a Windows 8 or Windows server 2012 machine. The script is expected to work from either of these operating systems only as per the support matrix in TechNet gallery.

C:\local\Convert-WindowsImage.ps1   -SourcePath "D:\local\Windows8.1.ISO" `
                                    -VHDFormat VHDX `
                                    -Edition ServerDataCenterCore `
                                    -VHDPartitionStyle GPT `
                                    -Verbose

This will start the VHDX creation process and approximately 20-30 minutes, you will have the VHDX file ready.

Once the VHDX file is ready, you need to add the file to boot menu on your existing OS installation, so that you can choose to boot from it when are the boot OS selection menu.

To achieve this, you follow the below instructions.

  • Backup your existing boot menu(BCD store) using /export switch of bcdedit.exe utility. Example, bcdedit /export c:\bcdbackup
  • Execute the below command and note the GUID along with braces retuned from the command.

bcdedit /copy {default} /d “VHD BOOT”

  • In my case it returned {d15fb411-28c6-11e3-be8c-1c3e847f665e} so the next commands will look like below. Make sure to replace my GUID with yours.

bcdedit /set {d15fb411-28c6-11e3-be8c-1c3e847f665e} device vhd=[D:]\local\windows.vhdx

bcdedit /set {d15fb411-28c6-11e3-be8c-1c3e847f665e} osdevice vhd=[D:]\local\windows.vhdx

  • This completes the process for adding entries for boot menu.
  • Now restart your laptop and you should see the VHD BOOT in your boot menu and choose it to boot through the VHD you just created.

If you receive errors messages from Mount-DiskImage (like “Mount-DiskImage : The version does not support this version of the file format”) while using the Convert-WindowsImage.PS1, then you can extract the ISO contents to a folder (I used 7-zip) and pass the WIM file to –SourcePath parameter of the script as shown below. Basically, the problem here is, Mount-DiskImage is failing to mount the ISO files to read the installation media.

Finally, a BIG thanks to this script author and you can read more about this script at http://gallery.technet.microsoft.com/scriptcenter/Convert-WindowsImageps1-0fe23a8f

Happy learning

{ 1 comment }

If you are using a Windows 8 PC, but this time you must be knowing that there are two types of apps in this OS. One type is “Store application” and another is “Desktop application”. I don’t want to go in detail about explaining differences between them, but want to say in nutshell that, store application is something you install directly from windows store maintained by Microsoft. These apps are designed specially for touch screen users. Built-in Skype, Citrix Receiver are classic examples of this application in Windows 8.1. Desktop applications is same like what we have in previous versions of operating systems where installation is via MSI/MSP and usage is same as the we way we use applications in previous versions.

Keeping the differences aside, I want to show you how to query applications installed via Windows store on Windows 8.1 OS and uninstall them.

Windows 8.1 has a module called Appx for managing apps installed via Windows Store. The Get-AppxPackage cmdlet will help us to list all store installed applications. Look at the below screen.

Get-AppxPackage | select Name
get-appxpackage-listapps

Name is the most appropriate parameter to recognize the application in the output. I looked for exact display names but no such attribute in the output.

Once you have the list, identify the software that you are planning to uninstall and make a note of its name. In my case, I tried to uninstall “D50536CD.CitrixReceiver” which is the name for Citrix Receiver. This app is not working fine on my computer so decided to uninstall it so that I can get desktop version of this application.

To uninstall a windows store application we can use Remove-AppxPackage cmdlet. The usage is simple as shown below.

Get-AppxPackage | ? {$_.Name -eq "D50536CD.CitrixReceiver" } | Remove-AppxPackage

uninstall store app

Once uninstalled, you can again verify to see if it still exists.

Get-AppxPackage | ? {$_.Name -eq "D50536CD.CitrixReceiver" }

verify uninstallation

Hope this helps and happy learning.

{ 0 comments }

PowerShell: Show/Get a browse folder window

In today’s post, let us see some more useful methods inside shell.application com object. In previous post, I showed you how to get desktop icons status. In this post, I will demonstrate, how to display a window using which user can browse and select folder. You know what I am talking? Look at the below screenshot for clarity.

You no need to use any C#, dotnet, WPF stuff to get this. The script completely replies on Shell.Application COM object. This COM object has a method called BrowseForFolder using which we can generate this window. The selection is returned in the form of a object which we can process to get the path user selected via the window.

Code:

function Get-OutputFolder {            
 [CmdletBinding()]            
 Param(            
 )            

 $Shell = New-Object -ComObject "Shell.Application"            
 $Folder = $Shell.BrowseForFolder(0,"Choose Output Folder",0)            
 if($Folder) {            
  return $Folder.self.Path            
 } else {            
  Write-Warning "No folder selected"            
 }            

}

Output:

browseforfolder-output1 browseforfolder-output2

Happy learning.

{ 0 comments }

I came across this question sometime back. One of the member in a forum was asking if there is a way to find what is the status of icons visibility status on desktop. That means if the “Show Desktop Icons” option in desktop ->Right Click -> View is selected or not.

show-desktop-cons

I came across answer for this while exploring Shell.Application COM class. It has a method called GetSetting() which can return some of the shell properties. One of them is desktop icons visibility status.

Below small function can help you determine the status.

Code:

function Test-DesktopIconHiddenStatus {            
[CmdletBinding()]            
Param(            
)            

$shell = New-Object -ComObject "Shell.Application"            
if($shell.GetSetting("0x00004000")) {            
 Write-Host "Desktop icons are hidden"            
} else {            
 Write-Host "Desktop icons are visible"            
}            

}

Output:

showdesktopstatus-outputHappy learning…

{ 1 comment }

Get active window on desktop using PowerShell

In today’s post, I want to show how to know what is the active window on Desktop.  I came across this requirement when I want to determine, what is the application user is currently using. There is no PowerShell CMDLET that can do this straight away, so we need to rely on a bit of C# coding to achieve this.

The user32.dll DLL provides function called GetForegroundWindow which provides the window handle of active application/process. We can find the process name by Get-Process with returned window handle.

Code:

[CmdletBinding()]            
Param(            
)            
Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class UserWindows {
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}
"@            
try {            
$ActiveHandle = [Windows]::GetForegroundWindow()            
$Process = Get-Process | ? {$_.MainWindowHandle -eq $activeHandle}            
$Process | Select ProcessName, @{Name="AppTitle";Expression= {($_.MainWindowTitle)}}            
} catch {            
 Write-Error "Failed to get active Window details. More Info: $_"            
}

Output:activewindow-using-powershell

You can download this script from Technet Gallery as well.

{ 8 comments }

In past I have written on the same subject. That was based on “WMPlayer.OCX.7” object which seems to be failing in some of the cases. I stumbled on a COM object today which I can use reliably to eject CD/DVD drive without issues. There are some more approaches as well available in internet which use a C# code in PowerShell. They also will work as expected but this is in pure form of powershell.

IMAPI(Image Mastering API) Interface in Windows has several abilities in managing the CD/DVD/BD disk drives and the COM objects I used in my below script are from the same family.

The script is short and straightforward.

[CmdletBinding()]            
param(            
[switch]$Eject,            
[switch]$Close            
)            
try {            
    $Diskmaster = New-Object -ComObject IMAPI2.MsftDiscMaster2            
    $DiskRecorder = New-Object -ComObject IMAPI2.MsftDiscRecorder2            
    $DiskRecorder.InitializeDiscRecorder($DiskMaster)            
    if ($Eject) {            
     $DiskRecorder.EjectMedia()            
    } elseif($Close) {            
     $DiskRecorder.CloseTray()            
    }            
} catch {            
    Write-Error "Failed to operate the disk. Details : $_"            
}

I published this script on Technet Script library as well. You can download it from there

{ 3 comments }

Get ESX host name from VM using PowerCLI

How to get ESX Host name of a guest VM using VMware PowerCLI? I came across this question in “Hyderabad PowerShell User Group” FB Group where I participate. Let us see how to achieve this using VMware PowerCLI.

There are various ways to query information of your VMware infrastructure but out of them PowerCLI is more efficient and recommended way.

To query any information from VMware infrastructure, first we need to connect to Virtual Center(VC) from the PowerCLI console. You can download it from VMware official website.

The first thing we need to do after installing and launching PowerCLI console is, connecting to the VC. The PowerCLI talks directly with the VC API and for that it needs to establish a connection. To do that you can use the below command.

Connect-VIserver -Server "VCSERVER1"

After Connection, let us get a object of VM for which you want to know ESX Host name.

$VMName = Get-VM -Name "myvmpc1"

Get-VM is a cmdlet that queries the VC for given VM name and returns the VM object. This object We are storing in $VMName variable.

Now you can get the ESX host name by using VMHost property of the VM Object.

Write-Host "ESX Host name is $($VMName.VMHost)"

or you can get this by using another cmdlet called Get-VMHost to which you have to pass the VM object.

Get-VMHost -VM $VMName

Below is a small function which takes multiple VM names as input and saves the VM name and respective ESX host name in CSV file.

function Get-VMESXName {            
[cmdletbinding()]            
param(            
[string()]$VMName            
)            

foreach($VM in $VMName){            
$VMObj = Get-VM -name $VM            
"{0} : {1}" -f $VM, $VMObj.VMHost | Out-File c:\temp\VMESXInfo.csv -append            

}            

}

Happy learning…

{ 0 comments }