Always A-HEAD, By being ahead you are always master of time

Hits

BOOKS

Monday, January 29, 2007

Hotfix by Powershell

Script is actually not about Hotfix but more about formatting. How you customize the format of output.

$Hotfix=Get-WmiObject Win32_quickfixengineering
$Bulk=@()
foreach($hotf in $hotfix) {

if($hotf.hotfixid -like "KB*") {
$Bulk += $Hotf
}
}

$Bulk format-table @{Label="HotFixID" Expression={$_.HotFixID}},
@{Label="InstalledBy"Expression={$_.InstalledBy}},
@{Label="InstalledOn"Expression={$_.InstalledOn}},
@{Label="Descr" Expression={$_.Description}} -autosize

The way you customize label and more important use of expression

To get more on this, I have two CSV files and my goal is to append data from both these files. I have imported here CSV but I 'm appending this csv file based on some critiera and that criteria here is Name.

Contents of Name-NC.csv

Name,NC
Shilpa,1
Paatu,1
Anju,2
Mom,3
Papa,3
Preetam,1

Contents of Name-City.csv

Name,City,Age
Preetam,Sng,30
Shilpa,Sng,26
Paatu,Ah,33
Anju,Kh,38
Mom,Ah,56
Papa,Ah,66

So I will check Name in Name-NC and append all the data if the name is present in Name-City.csv.

$NC=import-csv Name-NC.csv
$NCT=import-csv Name-City.csv
$BT =@()
$CT =@()
$Tot =@()
foreach ($Name in $NC) {
# write-host $Name.name `t $Name.NC
$CT =$Name.NC
$BT =$NCT where {$_.name -eq $Name.name}
$BT format-table @{Label="Name" Expression={$_.name}}, @{Label="City" Expression={$_.city}},
@{Label="Age"Expression={$_.Age}},
@{Label="Printer"Expression={$Name.NC}} }

above code I've mark it as bold. actually I got the whole data (again based on name)from one file and only got one detail from other file(Name-city) . Hope you would be able to use this funda somewhere.

Output:

Name City Age Printer
---- ---- --- -------
Shilpa Sng 26 1

Name City Age Printer
---- ---- --- -------
Paatu Ah 33 1

Name City Age Printer
---- ---- --- -------
Anju Kh 38 2

Name City Age Printer
---- ---- --- -------
Mom Ah 56 3

Name City Age Printer
---- ---- --- -------
Papa Ah 66 3

Name City Age Printer
---- ---- --- -------
Preetam Sng 30 1

Technorati tags:

IceRocket tags:

Wednesday, January 24, 2007

SurPriZED

hoey, I'm surprised to find me script on Microsoft site. Not because I don't know from where they came to know but I forgot I've send script to win some Goodies on occassion Powershell scripts. Certainly it is Goodies for me. It is very inspiring for me. This continues to fire my senses. http://www.microsoft.com/technet/scriptcenter/csc/scripts/media/itunes/index.mspx

Tuesday, January 23, 2007

Memory Dump configuration check

How to check if Server is configured to capture memory dump . Answer is in the code. From my personal experience whenever Servers faced Bluescreen, we check if the Memory dump file is created if not then we check few things if they are configured properly. Script below simply does it.

______________________________________________________________________

Write-Host ""

# ----------------->Get free space on C Drive where generally memory dump file is configured
$Cdrive=get-wmiobject -class win32_logicaldisk where {$_.deviceid -eq "c:"}
$CSpace=($Cdrive.FreeSpace/1MB)

#------------------->Converted it in KB's Since all other values are in KB's
Write-Host Free Space on C:\ $CSpace MB

#------------------>Lets get memory details of the computer
$TotalMemory=get-wmiobject win32_logicalmemoryconfiguration
$MEM=($totalmemory.TotalPhysicalMemory/1KB)
$PAGE=($totalmemory.Totalpagefilespace/1KB)
Write-host Physical RAM :- $MEM MB
Write-host Pagefile Size :- $Page MB

#------------------>Page file size should be atleast 12MB more than Physical RAM
$Recsize=($MEM+12)

if ($PAGE -ge $Recsize) {

#------------------>There should be enough free space on to capture memory dump.

if ($CSpace -ge $Recsize ) {
write-host "Machine should be able to generate kernel dump"
}
else {
write-host "Check disk Space on C: drive if memory dump file is configured on it"
}

#------------------>Crash control values are enumerated here
$CrashControl="hklm:\SYSTEM\CurrentControlSet\Control\CrashControl"
$CrashProp=$CrashControl Get-itemproperty
$CrashNo=$CrashProp.CrashDumpEnabled

#---------------->Switch used over here.

Switch($CrashNo) {

0 { "Memory is NOT configured" }
1 {"Complete memory dump is configured" }
2 {"Kernel memory dump is configured"}
3 {"Small memory dump (64KB)"}

}

Write-host Dump file location $CrashProp.DumpFile

$AutoNo=$CrashProp.AutoReboot
If ($AutoNo -eq "0") {write-host Auto Reboot is not enabled} else {write-host AutoReboot is enabled}

$CrashNo=$CrashProp.Overwrite
If ($CrashNo -eq "0") { write-host Overwrite Memory dump option is not enabled} else { write-host Overwrite Memory dump is enabled}

}

else {Write-Host "Page file size should be atleast 12MB more than RAM"}

Write-Host ""

______________________________________________________________________

OutPut:

Free Space on C:\ 4029056 KB
Physical RAM :- 1039744 KB
Pagefile Size :- 2500248 KB
Machine should be able to generate kernel dump
Kernel memory dump is configured
Dump file location C:\WINDOWS\MEMORY.DMP
Auto Reboot is not enabled
Overwrite Memory dump is enabled

----------------------------------------------------------

# References:
#
http://support.microsoft.com/kb/244139
#http://support.microsoft.com/kb/254649

#CrashDumpEnabled REG_DWORD 0x0 = None
#CrashDumpEnabled REG_DWORD 0x1 = Complete memory dump
#CrashDumpEnabled REG_DWORD 0x2 = Kernel memory dump
#CrashDumpEnabled REG_DWORD 0x3 = Small memory dump (64KB)

Technorati tags:

IceRocket tags:

Saturday, January 20, 2007

One Good Day

I discovered great thing today, you can divert the output of text file using out-file.

USAGE : .\RemoteSvc.ps1 . a* | Out-File services.txt

No big deal I know but it is always better to share it. I'm happy today as I was able to use powershell scripts in production enviornment and I was able to get satisfied results. Generally I don't check if the server is reachable, as result for few servers error was thrown. but script continued to work, for this to work in VBScript you will have to type

"On error resume next" at the top of text file or else script will exit

 

del.icio.us tags:

Technorati tags:

Wednesday, January 17, 2007

Computer Inventry with Powershell

I'm planning to put here series of code to get the computer inventory of machines. As you could remember last time I got the IP Address of the machine. This time I wanna know how many and what programs are installed on this machine.

$ALLPROGS=Get-ChildItem "hklm:\software\microsoft\windows\currentversion\uninstall" ForEach-Object {Get-ItemProperty $_.pspath}
if ($args -eq "sort" )

{
$ALLPROGS Select-Object displayname,publisher sort publisher

}
else

{

$ALLPROGS Select-Object displayname,publisher group publisher sort count

}

I've purposely left this code hanging whether you wish to have group programs or sort by name of the application publisher. Program is simple but fact that I would like to mentioned here, I tried the other way round, which I've pasted just for the sake of not to do do this.

USAGE: .\AllPrograms02.ps1 sort or .\AllPrograms02.ps1

$ALLPROG="hklm:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
$CHILDPROG=get-childitem $ALLPROG
$PROGNAME=$CHILDPROG select-object pschildname
for($i=0;$i -lt $PROGNAME.length; $i++) {
$EACHPROG=$PROGNAME[$i].pschildname
$PROGS="hklm:\Software\Microsoft\Windows\CurrentVersion\Uninstall\$EACHPROG"
$PROGS get-itemproperty select-object displayname,publisher sort displayname
}

Even though I have mentioned sort by displayname it won't work, sorting fails here because it has to be with POST here...

http://blogs.msdn.com/powershell/archive/2007/01/11/sorting-out-groupby.aspx, just though of keeping it in my mind. Please bear in mind this is not going to work on remote computer, But for me it doesn't matter. Because I'm going to run this everytime I built the server or someone asks me or Best one is to do by using psexec..hahaha. But certainly in future there is would be simpler way to run this across enterprise.

Technorati tags:

del.icio.us tags:

IceRocket tags:

Monday, January 15, 2007

Accessing Registry using PowerShell

Accessing registry is quite common in Powershell Now, so lets get into it. Idea was to gather inventory of entire computer. I thought lets start with simple code.

$regpath="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
$items=$regpath get-itemproperty
$items.RegisteredOwner
$items.systemroot
$items.SourcePath

Then I felt like exploring little more. I came with Idea of getting IP address of machine. When I wrote code I felt it was easy but it went too long than I felt.

$NICSPOOL="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards"
$NOSNIC=get-childitem $NICSPOOL
$EACHNIC=$NOSNIC select-object pschildname
for($i=0;$i -lt $EACHNIC.length; $i++) {
$CardName=$EACHNIC[$i].pschildname
#Write-host CNAME $CARDNAME
$NICCARDS="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\$CardName"
$NICPROP=$NICCARDS Get-ItemProperty
$SVCNAME=$NICPROP.ServiceName
#Write-host $SVCNAME
$Des=$NICPROP.Description
Write-host $Des
$IPPOOL="HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
$IPS=$IPPOOL + "\" + $SVCNAME
write-host IPS $IPS
$IPPROP=$IPS Get-itemproperty
#$IPPROP
if ($IPPROP.EnableDHCP -eq 1) {
Write-host IPAddress $IPPROP.DhcpIPAddress
Write-host SubnetMask $IPPROP.DhcpSubnetMask
Write-host DefaultGateway $IPPROP.DhcpDefaultGateway
Write-host DhcpServer $IPPROP.DhcpServer
}
if ($IPPROP.EnableDHCP -eq 0) {
Write-host IPAddress $IPPROP.ipaddress
Write-host SubnetMask $IPPROP.SubnetMask
Write-host DefaultGateway $IPPROP.DefaultGateway
Write-host DNSServer $IPPROP.NameServer
}
write-host ""
}

Few interesting things I discovered I've marked as pink.Above script assumes you have multiple NIC, nowadays it is more common. And I wanted this script to be enterprize compatible. Script would look for one parameter, DHCP if it is enabled it will get different out. Script did what I wished but only in parts. Again this won;t work across enterprize. So next step was googling.

Found

http://abhishek225.spaces.live.com/blog/cns!13469C7B7CE6E911!145.entry

http://mybsinfo.blogspot.com/2007/01/powershell-remote-registry-and-you-part.html

Both the blogs are quite interesting to an extend which explains remote registry access is possible.

Let's take simple example

LOCAL REGISTRY ACCESS

$regpath="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\2"
$items=$regpath get-itemproperty
$items.Servicename

REMOTE REGISTRY ACCESS

$Srv="Singaporelt"
$key = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$regKey = $regKey.OpenSubKey($key)
Write-Host "Sub Keys"
Write-Host "--------"
Foreach($sub in $regKey.GetSubKeyNames()){
$NICPOOLS = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\$sub"
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $Srv)
$regKey = $regKey.OpenSubKey($NICPOOLS)
Foreach($val in $regKey.GetValueNames()) {
if ( $val -eq "Servicename") {
$Keyvalue= $regKey.GetValue("$val")
$Keyvalue
}
}
}

See the difference in code. No No....it is not about lines in the code but it is property and methods available in local registry are not easily available while accessing remote registry. I was able to get the IP address using remote registry class but output was not quite satisfying and code manipulation was nothing but another vbscript. Yeah I can't expect best of both the worlds...not so early. For simple reason, without .net knowledge struggle will continue.

Friday, January 12, 2007

iPHONE

With due release of iPhone, mobile phone market is going to change. Innovation always takes lead. Competitive product O2,HP PDA’s will also need to change their game in order to stay in Market.

Another Article here is cool

I'm already planning one for me due in Asia 2008. It is pretty cheap when I compare with O2 Model.

Full specification of iPhone could be found at http://www.apple.com/iphone.


Thursday, January 11, 2007

Managing remote/local services with Pow6r Sh6ll

When I was exploring various possibilites from Admin point of view in Powershell, I was never aware that such CMDLET would not work for managing servers remotely. However it was not difficult to implement it when blogs like http://thepowershellguy.com/blogs/posh/ are available on the Internet. I happen to see MOW blog entry on blogspot (http://mow001.blogspot.com/)and there I realized yeah it is possible to do everything remotely same as sysinternal tools can do it. Again .NET Classes.With this idea in my mind, I was able to convert my all existing CMDLETS for managing stuff remotely. For doing this you should be aware of one very important thing, which classes to load. For example if you run this script as it, it will error out

"Unable to find type [System.ServiceProcess.ServiceController]: make sure that the assembly containing this type is loaded."

It means nothing but load the revelant classes before I can do anything. Let me admit it I don't know which class to load but to get it work you just run get-services before running the script below. It will internally load the relevant classes. Of course if the information comes from POWERSHELL GURU's, I will post it here.

Write-host $args[0]
$LikeVar= $args[1]
$remSVC=[System.ServiceProcess.ServiceController]::GetServices($args[0])
$remSVC where {$_.name -like $LikeVar}

Let's come to the script.

$args[0] which is standard variable(default) will pick first word which I have assigned for computername and second variable is your servicename string. Remember I have selected servicename not displayname to query.Above CMDLET is similiar to sc query findstr /i al*

NOW it is .\svcvar.ps1 computername al*. Much simpler.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Now there is scenario where in you need to stop three services on 200 servers across Enterprize. In fact I got this idea because I had dealt with it in reality and I have us SC STOP stuff which was quite murky in a way.

$Services=get-content "E:\PowerShell\MakesSense\Ser-ices.txt"
$Servers=get-content "E:\PowerShell\MakesSense\Servers.txt"
ForEach($Server in $Servers) {
$LOADSVC=[System.ServiceProcess.ServiceController]::GetServices($Server)
foreach($service in $services) {
$REMSVC=$LOADSVC where {$_.name -eq $service}
if ($REMSVC.status -eq "Running") {
Write-host $REMSVC.stop()
$REMsvc.WaitForStatus("stopped", (New-TimeSpan -seconds 3))
Write-host $REMsvc.displayname been successfully stopped on $server
}
elseif ($REMSVC.status -eq "Stopped") {
Write-host $REMsvc.displayname is already in $REMsvc.status state on $server -foregroundcolor "RED"
}
else {
write-host Please check if $service Service exists on $server -foregroundcolor "RED"
}
}
}

Write services which you wish to stop in ser-ices.txt and servers in servers.txt on which you wish to manage services. And then code is typical VBSCript code. Most important (new) thing here is how INFANTLY (Simply) I can manage output with $REMsvc.displayname, $REMsvc.status which Re-emphasize DO MORE WITH LESS Principle.

Technorati tags:
del.icio.us tags:
IceRocket tags:

Monday, January 08, 2007

Reading Eventlog before and after shutdown

$gener=Get-EventLog -LogName system where{$_.eventid -eq "6005"} sort timegenerated Select-Object -last 1
$timegen=$gener.timegenerated
$afterReb=get-eventlog -logname system where{$_.timegenerated -gt $timegen}
Write-host "-------------------------Error Type --------------------------- " -foregroundcolor "WHITE"
$afterReb Group-Object entrytype
#Start-Sleep -m 500
Write-host " "
Write-host "-------------------------ERRORS --------------------------- " -foregroundcolor "WHITE"
#Start-Sleep -m 500
$afterReb where{$_.entrytype -eq "error"} Select-Object timegenerated,Source,EventID,Message format-list out-host -paging
#$afterReb sort-Object entrytype format-list Out-Host -Paging
Write-host " "
$BforeShtdn=$timegen.addhours(-1)
Write-host "-------------------------Error 1 Hour Before ShutdownType --------------------------- " -foregroundcolor "WHITE"
$LsbforeShtdn=Get-EventLog -LogName system where{(($_.timegenerated -gt $BforeShtdn) -and ($_.timegenerated -lt $timegen))}
$LsbforeShtdn sort-Object entrytype format-list Out-Host -Paging

Suppose you get a call from Helpdesk, that system has gone unexpected shutdown.And now system is up but you wish to know why it went down.So first thing you look is event log. And what is your area of concentration. Obiviously when system went down and if there were any errors before and after shutdown. Exactly same thing this script does. It gets all event logs when system went down unexpectedly. Event ID in this case should be either 6008/6005, you can certainly include that logic here.But not only this I also got event logs before system went down for 1 hour duration. And I'm again amazed by $BforeShtdn=$timegen.addhours(-1), it is simple mathematics. I don't have to do programatically subtraction. Simple Superb. Thanks to Powershell team.

Well the script is again very simple, But it should be unique.I parsed the eventlog and filtered out 6005. I got all logs from after this event. Logically all events after system is shutdown.

Apart from the script above I found a very simple method to detect the uptime of any computer across the network.

$wmip=get-wmiobject Win32_PerfFormattedData_PerfOS_System -computername "SystemName"
$time=$wmip.SystemUpTime
$uptime=new-timespan -seconds $time
$formattime="{0:N}" -f $uptime
Write-host $formattime [Days:Hours:Minutes:Seconds]

Technorati tags:

IceRocket tags:

Friday, January 05, 2007

PowerShell EventLog Parser

#you need Error-Patters.txt which can include any pattern for example terminated failed Stopped unexpected

#----------------CODE BEGINS-------------------
$Patterns=get-content "E:\Powershell\Makesense\Error-Patters.txt"
foreach($Pattern in $Patterns) {
$Errevents = get-eventlog -logname system -newest 1000 where{$_.entrytype -eq "error"}
$failedpattern=$Errevents Select-Object eventid,timegenerated,message,source Select-String -Pattern $Pattern
Write-host "________________________" $Pattern "_______________________" -Foregroundcolor "RED"
for($i=0;$i -lt $failedpattern.length; $i++) {
[string]$splitt=$failedpattern[$i]
$splitt.Split(';')
Write-Host "_____________________ " -foregroundcolor "GRAY"
}
}

#--------------------CODE ENDS---------------------------


Yesterday I was going through basic of Powershell again. Just to see If I could dig out more. I came across select-string, Wow..another beautiful feature. I just wanted to utilized it's full powerBelow example is just sleek and does what things which always expect.
C:\PS>$events = get-eventlog -logname application -newest 100$events select-string -inputobject {$_.message} -pattern "failed"
Below is example in powershell inbuilt help. GET-HELP SELECT-STRING -EXAMPLES
Let's talk about the script. I'm basically going into system event log and then filtering only errors.Once I have errors I check content of the message for text likefailed,stopped,unexpected,terminated. Since this strings might differ in individually cases, I have included them in text file. One I thing I noticed here, output which select-string produceincludes message,eventid,source seperated by ";" So I have to use split command to manipulate the output. I have used again color backgrounds to make it more readable. I'm delighted by the output. Do try out.

Monday, January 01, 2007

Schedule reboot with PowerShell

$now=get-date

$MachineName=read-host "Please Enter Machine Name you wish to reboot :"

$When=read-host "Please enter time when you wish to reboot the server Later THAN ($now) :"

$results=$now.subtract($when)

#write-host $Results Results

$time2act=$now.Subtract($results)

#Write-host $time2act is time2act

$action=$time2act.subtract($now)

$Sec2Act= $action.totalseconds

$totalsecs="{0:N0}" -f $Sec2Act

$SecINint=[int]$totalsecs

write-host $testint

if($results -le 0)
{
write-host "done"
Write-host $MachineName "will Reboot in next " $SecINint Seconds
shutdown -s -m $machineName -t $SecINint
}
else {
write-host "Time entered has already past,please enter time later than " [$now] -Background "RED"
}

Due you remember days when you have to apply patches on 1000 servers in phased manner. But in this scenario servers are not rebooted, they are rebooted only when customer/client gives downtime. Such scenario needs a schedule reboot for the server. But what happens when each client gives different reboot time. I thought lets write something on similiar lines, where in we can schedule a reboot of the server as per client's requirement. Above is just the logic, but the script requires few more additions. First is we need to read content of server name, time it is schedule to reboot, which is easily possible to read from text file. And certainly this is small step towards automation.

Here I was able to use shutdown.exe command without invoking wscript.shell, which I like the most, which was not possible to do with VBScript. If you run this command you would get computer name prompt, time to enter in specific format and that it. I have tested the script. But I think it will require little more finishing.

Technorati tags:
;
del.icio.us tags:
;
IceRocket tags: