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

Hits

BOOKS

Thursday, March 01, 2007

Blogs Moved

All Blogs here are moved to

http://techstarts.wordpress.com/

Sorry, I feel wordpress editing much comfortable than...

Monday, February 19, 2007

Storage KB Articles for MSCluster

 

174617

Chkdsk runs while running Microsoft Cluster Server Setup

176970

Run the CHKDSK /F Command on a Shared Cluster Disk

250355

Antivirus Software May Cause Problems with Cluster Services

280353

How to Change Quorum Disk Designation

237853

Dynamic Disk Configuration Unavailable for Server Cluster Disks

259237

Troubleshooting Event ID 9, 11, and 15 on Cluster Servers

223023

Enhanced Disk Resource Private Properties Using Cluster Server

263590

How to Extend the Space of Existing Shared Disks with Windows Clustering

224508

How to Migrate Dfs Root Configuration to a Windows 2000 Cluster

224969

How to: Configure Event Log Replication in Windows 2000 Cluster Servers

226108

Cannot Place Swap File on a Windows NT Cluster Shared Disk

238137

Considerations when you create clustered file shares on a Windows 2000 or Windows Server 2003 server cluster

249194

MSCS/Cluster Does Not Form with Error Messages 170 and 5086

248998

How to Properly Restore Cluster Information

254219

Security Considerations When Implementing Clustered File Shares

256926

Implementing Home Folders on a Server Cluster

257897

MSCS printer shares may not come online if quorum log is too small

259243

How to set the startup value for a resource on a clustered server

262797

Reparse Point Support in Windows 2000-Based Clusters

269137

Some Cluster Server File Share Resources Are Not Available

280125

Cluster Administrator Switches for Connecting to a Cluster

278365

How to Configure Disk Quotas for a Shared Disk in a Cluster

280743

Windows Clustering and Geographically Separate Sites

278710

No Global Groups Are Available Creating File-Share Resource Permissions in Cluster Administrator

278951

The Cluster Internet Protocol Address May Not Come Online After the Quorum Disk Is Corrupted

284838

How to Create a Server Cluster File Share with Cluster.exe

293778

Multiple-Path Software May Cause Disk Signature to Change

245762

Recovering from a Lost or Corrupted Quorum Log

257389

Microsoft Cluster Server May Not Share Folders Automatically

223023

Enhanced Disk Resource Private Properties Using Cluster Server

259267

Microsoft Cluster Service Installation Resources

Windows Server 2003

283715

The Features of the Local Quorum Resource on Windows Server 2003 Cluster

284134

Server Clusters Do Not Support GPT Shared Disks

245762

Recovering from a Lost or Corrupted Quorum Log

175761

Dynamic vs. Basic Storage in Windows 2000

198513

Clustering Cannot Determine If a Shared Disk Is Working Properly

251186

Best Practices for NTFS Compression

290987

Error 3 When Creating a File Share on a Cluster with the Application Wizard

302539

How to Troubleshoot Printing Issues on a Windows Server 2003 Cluster

301647

Cluster Service improvements for Storage Area Networks (SANs)

304415

Support for Multiple Clusters Attached to the Same SAN Device

306640

A Removed Disk Can Have Its Corresponding Cluster Resource Started

312090

Cannot Use 32-Bit Resources on a 64-Bit Server Cluster

318534

Best Practices for Drive-Letter Assignments on a Server Cluster

280297

How to Configure Volume Mount Points on a Clustered Server

296799

How to Configure Windows Clustering Groups for Hot Spare Support

301588

How to Use DFS on Server Cluster to Maintain a Single Namespace

302829

Cluster Service Does Not Remove File Share Entries from LANMANSRVR

304736

How to Extend the Partition of a Cluster Shared Disk

310072

Adding support for more than eight LUNs in Windows Server 2003 and Windows 2000

305547

Support for Booting from a Storage Area Network (SAN)

1LooksAlive is a cursory status check that runs every 5 seconds (default). This routine simply checks that the disk status is not marked failed. LooksAlive is a cursory status check that runs every 5 seconds (default). This routine simply checks that the disk status is not marked failed. IsAlive is a more thorough check and occurs every 60 seconds (default). This routine checks that the disk status is not marked failed. If status is not failed, then FindFirstFile runs on the root of the disk to make sure the file system is still mounted and the disk is accessible

 

Sunday, February 18, 2007

AD Infrastructure from No Man's Land View

There are people who knows why it happens, there are people who explain how to make it happen and there are people who use the above two concept for their own customization.

Suppose one day your manager asks to get over to the role of Active directory team lead. First question that comes to mind, is there any AD Infra documentation about it, In most case it is not. But with powershell by your side, it is simple to get these details. Lets start with Forest

 

$forest=[system.directoryservices.activedirectory.forest]::getcurrentforest()
write-host ""
Write-Host "Forest Mode :" $forest.Get_forestmode()
write-host ""
Write-Host SCHEMA ROLE OWNER
$forest.SchemaRoleOwner | select Name,Domain,IPAddress,sitename,OSVersion
if($forest.SchemaRoleOwner.IsGlobalCatalog()) {write-host $forest.SchemaRoleOwner.name is GC}
write-host ""
Write-Host NAMING ROLE OWNER
$forest.namingRoleOwner | select Name,Domain,IPAddress,sitename,OSVersion
if($forest.namingRoleOwner.IsGlobalCatalog()) {write-host $forest.namingroleowner.name is GC}
write-host ""
Write-host "SITES AND ITS LOCATION"
$forest.Sites | %{$_.name,$_.location}
Write-host "Number of sites "$forest.Sites.Count
#Global Catalogs
Write-host Number of GC : $forest.FindAllGlobalCatalogs().count
write-host ""
Write-Host "ALL GC'S NAME"
$forest.FindAllGlobalCatalogs() | %{$_.name}

OUTPUT:

Forest Mode : Windows2000Forest

SCHEMA ROLE OWNER

Name : snguatser.Zarays.com
Domain : Zarays.com
IPAddress : 192.168.100.110
SiteName : Default-First-Site-Name
OSVersion : Windows Server 2003

snguatser.Zarays.com is GC

NAMING ROLE OWNER
Name : snguatser.Zarays.com
Domain : Zarays.com
IPAddress : 192.168.100.110
SiteName : Default-First-Site-Name
OSVersion : Windows Server 2003

snguatser.Zarays.com is GC

SITES AND ITS LOCATION
Default-First-Site-Name
Number of sites 1
Number of GC : 1

ALL GC'S NAME
snguatser.Zarays.com

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

 

$domain=[system.directoryservices.activedirectory.domain]::getcurrentdomain()
Write-host Domain_Name: $domain.name
write-host Forest_Name : $domain.Forest.name
write-host Domain_Mode: $domain.DomainMode

Write-Host (""*25 + "Domain Controllers" + ""*25)
Write-Host Number of DC : $domain.DomainControllers.Count
Write-Host Domain controllers details:->
$domain.DomainControllers | %{$_.name,$_.IPAddress,$_.sitename,$_.osversion}
write-host ("-"*60)
Write-Host "Infrastructure Master Role :"
$domain.InfrastructureRoleOwner | fl Name,OSVersion,IPAddress,Sitename
if($domain.InfrastructureRoleOwner.IsGlobalCatalog()) {write-host $domain.InfrastructureRoleOwner.name is Global Catalog}
write-host (""*60)
Write-Host "PDC Master Role :"
$domain.pdcRoleOwner | fl Name,OSVersion,IPAddress,Sitename
if($domain.PDCRoleOwner.IsGlobalCatalog()) {write-host $domain.PDCRoleOwner.name is Global Catalog}
write-host (""*60)
Write-Host "RID Master Role :"
$domain.ridRoleOwner | fl Name,OSVersion,IPAddress,Sitename
if($domain.ridRoleOwner.IsGlobalCatalog()) {write-host $domain.ridRoleOwner.name is Global Catalog}
write-host""

OUTPUT:

Domain_Name: Zarays.com
Forest_Name : Zarays.com
Domain_Mode: Windows2000NativeDomain
Domain Controllers
Number of DC : 1
Domain controllers details:->
snguatser.Zarays.com
192.168.100.110
Default-First-Site-Name
Windows Server 2003
------------------------------------------------------------
Infrastructure Master Role :

Name : snguatser.Zarays.com
OSVersion : Windows Server 2003
IPAddress : 192.168.100.110
SiteName : Default-First-Site-Name

snguatser.Zarays.com is Global Catalog

PDC Master Role :

Name : snguatser.Zarays.com
OSVersion : Windows Server 2003
IPAddress : 192.168.100.110
SiteName : Default-First-Site-Name

snguatser.Zarays.com is Global Catalog

RID Master Role :

Name : snguatser.Zarays.com
OSVersion : Windows Server 2003
IPAddress : 192.168.100.110
SiteName : Default-First-Site-Name

snguatser.Zarays.com is Global Catalog

That's all for this post. It is simple idea what you can idea from CMDlets without even going through all places collecting and documenting this information. SInce my test machine doesn't include multiple domains, I can really get hold of better formatting.

Sunday, February 11, 2007

Daily logs of DiskSize

I truly believe in learning new things and try out new things. Even there could be more than one way of doing it, it makes me crazy to put old things in new way, because you never new that it could be done in this way.

$Cusdate=(get-date).tostring("ddMMyyyy")
$file=new-item -type file "$Cusdate-freedisk.txt"
get-content "E:\PowerShell\Outputfiles&Folders\servers.txt" | % {

if((get-wmiobject win32_pingstatus -Filter "address='$_'").protocoladdress) {
$wmiObj=gwmi win32_logicaldisk -filter "deviceid='c:'" -computer $_
$freesp="{0:N02}" -f ($wmiObj.freespace/1MB)
$Totalsp="{0:N02}" -f ($wmiObj.size/1MB)
add-content $file "Total Size on C Drive of $_ : $Totalsp (MB)"
add-content $file "Free Size on C Drive of $_ : $Freesp (MB)"
}

else {
write-host $_ is not reachable -foreground "RED"
$Doubleline = ("="* 60)
add-content $file $Doubleline
add-content $file "$_ is not reachable"
}
}

http://thepowershellguy.com/blogs/posh/archive/2007/02/08/sesame-powershell-scripting-text-files.aspx

Above link is where the original code and Idea resides. I've modified it little but to look more like PowerShell.

Output is:

 

 

 

 

 

 

New things learnt:

$Cusdate=(get-date).tostring("ddMMyyyy") you can customize the date format.

Below is single line which will check if server is online, cause it makes sense before you do anything on the server, to make sure it is live.

if((get-wmiobject win32_pingstatus -Filter "address='$_'").protocoladdress) this will return true if server is live.

 

IceRocket tags: , ,

del.icio.us tags: , ,

Technorati tags: , ,

Thursday, February 08, 2007

Managing groups in Active Directory with Powershell

Let's do something with groups in Active directory, I have couple of users and one group under OU named Singapore. My intention here is to modify only user accounts and not group so I have condition them with SamAccountType.

$SNGOU=new-object directoryservices.directoryentry("LDAP://ou=singapore,DC=zarays,dc=com") # Let's connect to OU name Singapore
$UserObject=$sngou.psbase.Children # Lets get the object under OU

foreach($user in $userobject) {
if ($user.sAMAccountType -eq 805306368) { # we want to just update user object and not group object
$user.put("Description","Storage Admins") # We change the description to Storage Admins
$user.setinfo() # Commit changes
}
}


Let's create a group in Singapore OU :

$SNGOU=new-object directoryservices.directoryentry("ldap://ou=singapore,DC=zarays,dc=com/") # Let's connect to OU name Singapore
$Grp=$SNGOU.psbase.Children.Add("CN=Storageadmins","group")

$grp.psbase.commitchanges()

Group is created. Now lets add member to this group. Assuming there are several users in OU, we will only add user whose department is Provisioning. But before I go to the code, I would like to share something with you. You won't see member property if you do

$Grp | gm

or $grp.member

cause there is nothing to display but moment you add user, the next moment you do

$grp | gm

you will see member property.

If you are as beginner like me & would like to know the property, simplest way is to use google. After searching 4 hours I got to know Oh what is happening. And similiarly there is attribute called managedby, it is also having same story. There might be many.

$grp.managedBy.Value

$grp.managedBy.Add("CN=Preetam,OU=Singapore,DC=Zarays,DC=com")

$grp.psbase.CommitChanges()

Let's get to adding members to the group. Remember one thing if your CN name has space you will have to use quotes [$grp.member.add("$DN")].

Also you need a distinguished name in order to add it to any particular group, which is quite logical cause it confirms user object is present and where is it.

$Grp=new-object directoryservices.directoryentry("LDAP://cn=storageadmins,ou=singapore,dc=zarays,dc=com") # GRP -Connection
$SNGOU=new-object directoryservices.directoryentry("
LDAP://ou=singapore,DC=zarays,dc=com") #OU -Connection
$UserObject=$sngou.psbase.Children
# Populate childs in OU

foreach($user in $userobject) {
$DN=$user.distinguishedName
# Get there distinguished name
if ($user.department -eq "Provisioning") {
$grp.member.add("$DN")
#Add them to group

$grp.setinfo() # Commit changes

}
}

There is very good post available on http://janssenjones.typepad.com/, I liked it very much for adding members to the group.

Again there is very very stuff on internet but this cooked by me and I always like to eat that way. And my experience hopefully will help you all.

Tuesday, February 06, 2007

CoolOne with Powershell

Yesterday there was question in KBC , English version[Original] Who wants to be Millionaire, how many 9's are there from 1 to 100. Before they could answer I answered it quickly with Powershell. This is how

(1..100 where{$_ -like "*9*}).count

Monday, February 05, 2007

Bulk User Creation using PowerShell

When we think of making any changes in AD, we must start at creating objects. And as always first thing that comes to Mind is to create multiple users. And again here reference are same as previous one's MOW and Arulk. MOW's concept is used but methods I have to use from Arulk, cause things work.

Usually you get a excel sheet from the HR etc dept, I would always convert it into CSV since PowerShell will do the magic for me.

Contents of CSV file [Busers.csv]

Below are the headers of the CSV file and you can fill in the data.

CN,SN,GivenName,Name,Title,Description,PostalCode,TelephoneNumber,Department,Company,StreetAddress,Countrycode,SamAccountName,userPrincipalName,Mail,HomePhone,mobile.

I've shared the CSV file using google docs. Click Here

I'm going to create bulk users in India OU, which is under Zarays' OU

$IndiaOU=[ADSI]LDAP://localhost:389/ou=India,dc=zarays,dc=com
# Connecting to India OU

$UserDetails=Import-Csv "Buser.csv" #-----importing bulkusers data

foreach($UD in $UserDetails) { #--------looping into csv file and

# Passing all data into variables
$CN=$UD.CN
$SN=$UD.SN
$title=$UD.title
$description=$UD.description
$department=$UD.department
$streetAddress=$UD.streetAddress
$postalcode=$UD.postalcode
$telephoneNumber=$UD.telephoneNumber
$givenName=$UD.givenName
$company=$UD.company
$mail=$UD.mail
$homePhone=$UD.homePhone
$mobile=$UD.mobile
$userPrincipalName=$UD.userPrincipalName
$Samaccountname=$UD.Samaccountname

$Indiauser=$IndiaOU.create("user","cn=$cn") #I created actual user here and later I'm

#filling all properties for user
$Indiauser.Put("sAMAccountName",$Samaccountname)
$Indiauser.put("SN",$SN)
$Indiauser.put("Title",$Title)
$Indiauser.put("Description",$description)
$Indiauser.put("department",$department)
$Indiauser.put("streetAddress",$streetAddress)
$Indiauser.put('Postalcode',$postalcode)
$Indiauser.put('telephoneNumber',$telephoneNumber)
$Indiauser.put('givenName',$givenName)
$Indiauser.put('company',$company)
$Indiauser.put('mail',$mail)
$Indiauser.put('homePhone',$homePhone)
$Indiauser.put('mobile',$mobile)
$Indiauser.put('userPrincipalName',$userPrincipalName)

$Indiauser.setinfo() #All data committed. There are lots of other properties you can

#add
}

Below here I'm doing two things, First is enable the user and second set password. Because for some reason I'm not able to get these two things done in above loop. It throws exception. But I'm sure it can be included.

$IndiaOU=new-object directoryservices.directoryentry("LDAP://ou=India,dc=zarays,dc=com")
$UserDetails=Import-Csv "Buser.csv"

$userdetails=$IndiaOU.psbase.Children

foreach($UD in $UserDetails) {
$CN=$UD.CN
$accts=$IndiaOU.psbase.Children.Find("cn=$CN")
$accts.psbase.Invoke("SetPassword","P@ssW0Rd")
$accts.psbase.InvokeSet('Accountdisabled',$false)
$accts.psbase.CommitChanges()
}

Last and least, I'm sure there much better CMDlets to do this job, but what makes me proud it that I've created this script and I understand it very well. As compare to those VBScript scripts available on the net, I can use it but can't customize it. Thanks GOD there is PowerShell Team of Blogs.

Technorati tags: ,

IceRocket tags: ,

del.icio.us tags: ,

UPDATED :Please check comment where you will see the reason Why code has been updated.

Marc !! Bingo here it goes..the way it should work.

$IndiaOU=[ADSI]"LDAP://localhost:389/ou=Singapore,dc=zarays,dc=com"$UserDetails=Import-Csv "latestusers.csv"
foreach($UD in $UserDetails) {

$CN=$UD.CN

$SN=$UD.SN

$title=$UD.title

$description=$UD.description

$department=$UD.department

$streetAddress=$UD.streetAddress

$postalcode=$UD.postalcode

$telephoneNumber=$UD.telephoneNumber

$givenName=$UD.givenName

$company=$UD.company

$mail=$UD.mail

$homePhone=$UD.homePhone

$mobile=$UD.mobile

$userPrincipalName=$UD.userPrincipalName

$Samaccountname=$UD.Samaccountname

$Indiauser=$IndiaOU.create("user","cn=$cn")

$Indiauser.Put("sAMAccountName",$Samaccountname)

$Indiauser.put("SN",$SN)

$Indiauser.put("Title",$title)

$Indiauser.put("Description",$description)

$Indiauser.put("department",$department)

$Indiauser.put("streetAddress",$streetAddress)

$Indiauser.put('telephoneNumber',$telephoneNumber)

$Indiauser.put('givenName',$givenName)

$Indiauser.put('company',$company)

$Indiauser.put('mail',$mail)

$Indiauser.put('homePhone',$homePhone)

$Indiauser.put('mobile',$mobile)

$Indiauser.put('userPrincipalName',$userPrincipalName)

$Indiauser.setinfo()

$Indiauser.psbase.Invoke("SetPassword","P@ssW0Rd")

$Indiauser.psbase.InvokeSet('Accountdisabled',$false)

$Indiauser.psbase.CommitChanges()

}

Sunday, February 04, 2007

[DSQuery]-With PowerShell

[DSQuery]-With PowerShell

Below post talks about querying AD. However before you go through this post I strongly recommend you go through below link from

MOW : - http://mow001.blogspot.com/2006/09/powershell-rc2-and-active-directory.html

Let me admit it that below post are original ideas and concept by MOM, here at the most I using better formatting and pulling out corollary out of it.


Connect to AD

[adsi]''
$root=[adsi]'' or $root=new-object directoryservices.directoryentry


List properties of AD Objects

$root fl *


List methods of AD Objects

$root.psbase gm -membertype method # Get all methods

Walk to the Domain structure to wanted OU

$root.psbase.Children

distinguishedName
-----------------
{CN=Builtin,DC=Zarays,DC=com}
{CN=Computers,DC=Zarays,DC=com}
{OU=Domain Controllers,DC=Zarays,DC=com}
{CN=ForeignSecurityPrincipals,DC=Zarays,DC=com}
{OU=France,DC=Zarays,DC=com}
{OU=India,DC=Zarays,DC=com}
{CN=Infrastructure,DC=Zarays,DC=com}
{CN=LostAndFound,DC=Zarays,DC=com}
{CN=NTDS Quotas,DC=Zarays,DC=com}
{CN=Program Data,DC=Zarays,DC=com}
{OU=Singapore,DC=Zarays,DC=com}
{CN=System,DC=Zarays,DC=com}
{OU=UK,DC=Zarays,DC=com}
{CN=Users,DC=Zarays,DC=com}

$users=$root.psbase.children.find('CN=Users') or $users=new-object directoryservices.directoryentry("LDAP://CN=Users,DC=Zarays,DC=com")

-To get properties of user containers

$users fl *

-To find user in a container

$users.psbase.Children.Find('cn=Preetam')

$users.psbase.Children.Find('cn=Preetam') fl *

Corollary 01

Lets use this feature.

$preetam=$users.psbase.Children.Find('cn=Preetam')

$shilpa=$users.psbase.Children.Find('cn=shilpa')

Compare-Object $preetam.memberOf $shilpa.memberOf

Output is

InputObject SideIndicator
----------- -------------
CN=Domain Admins,CN=Users,DC=Zarays,DC=com <=
CN=Enterprise Admins,CN=Users,DC=Zarays,DC=com <=
CN=Schema Admins,CN=Users,DC=Zarays,DC=com <=

Which means Shilpa is not member of above group

Corollary 02

$OU=new-object directoryservices.directoryentry("LDAP://ou=Singapore,dc=zarays,dc=com")

$b=$ou.psbase.children
foreach($c in $b) {
$c.mail
}

output is Email address of all users inside OU singapore. And these address are generally required when you need to communicate back with your colleagues when you leave you current job cool

Friday, February 02, 2007

ACTIVE DIRECTORY AND POWERSHELL

I want to devote this and may be next month on Active directory and powershell.Just a simple search on google will lead you to very good posts by MOW.

I checked the datestamps and they where way back mid 2006.It is the best thing to start. Also Arul writes a lot on Ad mgmt. But lots of things changed with RC2. I'm looking forward to put same stuff in better format. And these are not only reference but there are lots articles on AD. However I'm looking forward to use powershell's power get proper format, in short MOre with less.

Broadly speaking there are always two things you do with Active directoy, Querying AD and committing changes to AD.

Both of these are very very interesting and I'm loving it with powershell by your side.

Within System.DirectoryServices there are two main classess

  • DirectoryEntry for creating objects [Committing changes]
  • DirectorySearcher for searching objects [Querying]

Let first create OU's

Out of it I got little things done by myself. I have created multiple OU's in one go.

$objUser = [ADSI]"LDAP://localhost:389/Ou=India,dc=zarays,dc=com" # Connection established with LDAP port
$readfile=get-content "E:PowerShellActiveDirectoryOUList.txt" # Reading file

foreach($readf in $readfile) {
$ou=$objUser.create("organizationalunit", "ou=$readf") #Creating OU
$ou.setinfo() # Committing changes
}

Following OU's are created assuming India ou is already there

  • Bangalore
  • Chennai
  • NewDelhi
  • Mumbai


Let's edit properties of OU here

$readfile=get-content "E:PowerShellActiveDirectoryOUList.txt"
foreach($ou in $readfile) {
$u=$ou + " Operations"
$OUC=new-object directoryservices.directoryentry("
LDAP://OU=$ou,OU=India,Dc=zarays,dc=com") #connect to OU
$ouc
$oUc.Put("description", $u) #Description but there is one more way to do this.
$oUc.SetInfo() # very important line, this where you says please commit what has been said above.
}

Descriptions changes to

  • Bangalore Operations
  • Chennai Operations
  • NewDelhi Operations
  • Mumbai Operations



Contents of oulist.txt

  • Bangalore
  • Chennai
  • NewDelhi
  • Mumbai

REF:

MOW

http://mow001.blogspot.com/2006/06/powershel-and-active-directory-part-1.html

ARULK

http://blogs.msdn.com/arulk/

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: