≡ Menu

Know about $OFS — a special variable in powershell

This is a new thing which I came across today. $OFS is a special variable that contains the string to be used as the Ouptut Field Seperator when an array is converted to a string.  By default, this is ” ” but you can change it.

PS C:temp1>
PS C:temp1> $a=(“a”,”b”,”c”,”d”)
PS C:temp1> $a
a
b
c
d

As you can see in above example, $a is a character array which has a,b,c,d as members. When you print them each character is coming in new line. If I convert this char array to string what is the expected output? “abcd” right? No…you are wrong… see below…

PS C:temp1> [string][char[]]$a
a b c d
PS C:temp1>

There is a space between each character. This happened because $OFS is coming into picture here and inserting a space between each character.

PS C:temp1> $OFS=”/”
PS C:temp1> [string][char[]]$a
a/b/c/d
PS C:temp1>

In the above code I have explicitly changed the $OFS value to “/” which made the conversion to insert a “/” symbol between characters. You can nullify $OFS to avoid any sort of delimiters when you convert a char array to string.

Hope this helps…

{ 3 comments }

I know many people have already figured it out in powershell way. I got similar requirement today morning where I have to check hardware make and model of 10 servers. That made me to recollect one of my old experience where I wrote a VB script to do the task. That time it took almost 2-3 hours to make the script ready. It took so long because of two reasons, number#1 I am new to VB scripting, number#2, I don’t know how to get this information. But it didn’t take that long today because of powershell as number#1 is not valid as I already gained some knowledge and number# as I already know from where I should get this info. So, I wrote below code in three minutes and gathered the output.

function get-hwinfo {

param($computer)

gwmi -query “select * from win32_computersystem” -computername $computer | select Name, Manufacturer, Model

}

$servers = Get-Content c:tempservers.txt

$servers | % { Get-hwinfo -computer $_ }

Hope this little code help you to pull the required information from servers.  I will try to write a script to gather complete hardware configuration when I get some time. 

Do you have a complete script which can get full hardware details? Share it.

{ 1 comment }

Have you ever experienced the scenario where you kept your PC under build and waiting for it to complete by sitting ideal in front of it? How about a facility which allows you to access application like IE, RDP, command prompt, task manager, etc while the system build is actually in progress? It’s possible in windows with a key stroke when the build is in GUI mode.

After you see build entering the GUI mode, press SHIFT + F10 and it will present you with a command prompt. From there on you can start the windows basic applications like iexplore.exe, taskmanager.exe using start from command prompt like below. I tested this on Windows 7 and works like a champ. Btw, this is a pretty old cheat that I used during windows XP installation almost 6 years ago.

C:> start iexplore.exe

C:>start taskmanager.exe

Hope this little tip helps you. I used this to see few log files while my build scripts are running for debugging purpose. With this I caught the errors early and took appropriate action without waiting for build completion.

Do you know any way better than this? Please share.

{ 0 comments }

I have a file with list of users with duplicate entries. My goal is to process this file and generate the duplicate list. I also need to know how many times a entry got repeated in file incase of duplication. This is the requirement I got today and I could able to fulfill this with less efforts using PowerShell.

So, here is the script.

$hash =@{}
$users = Get-Content c:\tempuserslist.txt
$users | % {$hash[$_] = $hash[$_] + 1 }
$hash.getenumerator() | ? { $_.value -gt 1 }

In above example, I used a hash table to keep track of number of entries of each. We can use arrays here but that won’t help you listing the duplicates count. If you would like read more details about hashes, please refer http://technet.microsoft.com/en-us/library/ee692803.aspx

{ 4 comments }

 

This small powershell command helps you to get the domain controller name currently in use.

PS C:> ([ADSI]”LDAP://RootDSE”).dnshostname
DC1.Techibee.com
PS C:>

You can also know to which site this DC belongs to.

PS C:> ([ADSI]”LDAP://RootDSE”).servername.tostring().split(“,”)[2].Split(“=”)[
1]
SITE1
PS C:>

Isn’t it looking a bit complex to query the site name? Any alternatives? Yes, we do have one. Below helps you to query the Site name of DC you connected.

import-module ActiveDirectory

Get-ADDomainController -Discover | select Site

Site
—–
SITE1

Note that above command requries ActiveDirectory PowerShell module which is generally available in Windows 7. One more requirement to make ActiveDirectory Module work agaist your Active Directory is, your DCs should have ADWS(active directory web services) installed. These services comes by default with windows 2008 servers but on windows 2003 servers you need to install this additional components.

Refer to my old article about Active Directory Administrative Center where I talked about ADWS for windows 2003.

{ 0 comments }

Sometimes you see incomplete data in powershell output. This kind of output ends with three dots(…) which resembles some data which shell is unable to display. Below is one such example, where I am trying to view the permissions of a folder via Get-Acl

Here, “Get-Acl | select access” works but will display similar output since it has more amount of data to display which cannot be accommodated into shell window. In such cases, to see the complete output, we can use a parameter named “-expandproperty”. This prints the complete value in shell.  Below is the example.

Get-ACL | select -expandproperty access

Hope this helps…

{ 1 comment }

Easily turn off your monitors to maintain privacy

Generally co-workers in office stop by your desk to seek some help or to throw some questions. That time you might be busy in middle of something and don’t want the person to see what is going on your screen. The general thing we do in such instances is, minimize all windows; but if you have some items on desktop, they are still visible to your visitor. So, now what should one do to blank the screen without disturbing the work?

I came across a nice utility (blacktop) which can be of some help here. This makes the screen blank with ctrl+alt+b key combination. Though using the key combination is bit difficult, I felt is useful.

{ 0 comments }

Goal:

To monitor the restart status of a computer. That means, to know what happened after initiating the restart; whether it rebooted? failed to initiate the reboot? failed to come back online?. This scripts helps to easily answer these questions.

Today I restarted one  server and kept a continues ping to know when it comes online. The command prompt window got buried behind other windows, as I switched from it to take care of some other task meanwhile. I completely forgot that I should monitor that ping output to determine if the server is going down and coming back or not. When I looked at the ping status it is showing replies…. Now I don’t know if went down and came back or never went down. Also I what would have happen if the server went down but had problems in coming up? Nothing will happen than increased service outage which is costly to the organization.  With all these thoughts, I logged into the server and checked uptime of it to confirm that it is rebooted.

At that moment I got a thought to write a simple script which monitors the server restart and alerts me after a certain timeout with the status? My script should also alert me in case my server fails to go down and if it fails to come up as well. In addition it should notify me when the server comes back online. My script is ready with initial functionality to check the status, but when it comes to notification, I want to have something different and fancy. Email will definitely do, but I don’t know when I will open INBOX. So, what I have done is configured system tray notifications with alert messages(thanks to jdhitsolutions for sample code ). Now I am ready with the script I want, Restart-Monitor.ps1

Initially I have used test-connection cmdlet to check the ping status of remote computer but it didn’t work the way I expected. So, I felled back to my old ping-host function.

Usage:

[PS]C:local>.Restart-Monitor.ps1 -computer server1 -timeout 10

Where server1 is the name of the remote server I am monitoring and timeout is the max time(in minutes) server takes to reboot.

Screenshots:

Successful Restart:

Failed to Start:

Failed to Shutdown:

****Disclaimer: Author is not responsible for any kind of damage made by this script. Use it at your own risk.

Code:(save this into restart-monitor.ps1 and excute it from powershell window)

Param (            
 [Parameter(ValueFromPipeline=$False,Mandatory=$True)]            
 [string]$computer,            
 [Parameter(ValueFromPipeline=$False,Mandatory=$False)]            
 [int]$timeout=5            
)            
            
$MAX_PINGTIME = $timeout * 60            
$max_iterations = $MAX_PINGTIME/5            
$Notification_timeout = 10 # in seconds            
            
function Show-notification {            
            
param($type,$text,$title)            
            
#load Windows Forms and drawing assemblies            
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null            
#define an icon image pulled from PowerShell.exe            
$icon=[system.drawing.icon]::ExtractAssociatedIcon((join-path $pshome powershell.exe))            
$notify = new-object system.windows.forms.notifyicon            
$notify.icon = $icon            
$notify.visible = $True            
#define the tool tip icon based on the message type            
switch ($messagetype) {            
 "Error" { $messageIcon=[system.windows.forms.tooltipicon]::Error}            
 "Info" {$messageIcon=[system.windows.forms.tooltipicon]::Info}            
 "Warning" {$messageIcon=[system.windows.forms.tooltipicon]::Warning}            
 Default {$messageIcon=[system.windows.forms.tooltipicon]::None}            
}            
            
#display the balloon tipe            
$notify.showballoontip($Notification_timeout,$title,$text,$type)            
}            
            
function ping-host {            
param($pc)            
$status = Get-WmiObject -Class Win32_PingStatus -Filter "Address='$pc'"            
if( $status.statuscode -eq 0) {            
   return 1            
} else {            
 return 0            
}            
}            
            
if(ping-host -pc $computer) {            
 Write-Host "$computer is online; Waiting for it to go offline"            
 $status = "online"            
 for ($i=0; $i -le $max_iterations; $i++) {            
  if (!(ping-host -pc $computer )) {            
   break            
  }            
  Start-Sleep -Seconds 5            
  if($i -eq $max_iterations) {            
   Write-Host "$computer never went down in last $timeout minutes"            
   Write-Host "Check that reboot is initiated properly"            
   show-notification -type "error" -text "$computer is still ONLINE; Check that reboot is initiated properly" -title "Computer is not rebooting"            
   exit            
  }            
    }            
            
    Write-Host "$computer is offline now; monitoring for online status"            
            
} else {            
    Write-Host "$computer is offline; Monitoring for online status"            
    $status = "offline"            
}            
            
for ($i=0; $i -le $max_iterations; $i++) {            
 if ((ping-host -pc $computer )) {            
  break            
 }            
            
 Start-Sleep -Seconds 5            
 if($i -eq $max_iterations) {            
  Write-Host "Your computer never came back online in last $MAX_PINGTIME seconds"            
  Write-Host "Check that nothing is preventing starup"            
  show-notification -type "error" -text "$Computer is NOT coming online; Something is preventing its startup" -title "Computer failed to start"            
  exit            
 }            
}            
            
Write-Host "Your computer is Online Now; Task done; exiting"            
show-notification -type "info" -text "$Computer is online" -title "$Computer successfully restarted"
{ 20 comments }

Tip: How to find variable type in PowerShell

We use variables in powershell without declaring them. That is so nice and eases the programming. But what to do when you really want to know what is the variable type that got created? We can’t go by evaluating the value assigned to the variable but there is a simple way the *Power*Shell.

"Hallo".GetType().FullName            

(4).GetType().FullName            

(2.6).GetType().FullName            

(Get-Date).GetType().FullName

If $myvariable is the one you are using, then just try $myvariable.gettype().fullname

Hope this tiny tip helps you..happy learning..

{ 2 comments }

Identifying and deleting hidden shares is one of the pressing problems for system administrators. In this post, I will explain you how to get list of hidden shares in a computer(s).

To list hidden share in local computer, simply run

gwmi -class win32_share | ? { ($_.type -eq “0” ) -and ($_.Name -match “w$”)}

The above oneliner gets list of shares in local computers and filters the disk type shares and looks for the share names that are ending with “$” symbol which indicates a hidden share.

You can simply run this against a remote computer by passing -computername parameter like below.

gwmi -computername <remotepc> -class win32_share | ? { ($_.type -eq “0” ) -and ($_.Name -match “w$”)}

Similarly, if you have a list of computers and you want to know the hidden shares, use the below two line code

$mycomputers = Get-Content c:tempmycomputers.txt

$mycomputers | gwmi -computername $_ -class win32_share  ? {($_.type -eq “0”) -and ($_.Name -match “w$”) }

In above code, first we are reading the list of computers into a variable and passing them one by one to our previous command which generates the list of hidden shares in remote computer.

Hope this helps.

{ 5 comments }