August 2007 - Posts
Here is a by request PowerShell script to add/remove a domain user to the Local Administrators group on a remote machine and you can easily make it to work on multiple remote machines using the technique in my previous script
# if your user name is whatever\test
$domain = "whatever"
$strComputer = "XYZ"
$username = "test"
$computer = [ADSI]("WinNT://" + $strComputer + ",computer")
$computer.name
$Group = $computer.psbase.children.find("administrators")
$Group.name
# This will list what’s currently in Administrator Group so you can verify the result
function ListAdministrators
{$members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
$members}
ListAdministrators
# Even though we are adding the AD account but we add it to local computer and so we will need to use WinNT: provider
$Group.Add("WinNT://" + $domain + "/" + $username)
ListAdministrators
$Group.Remove("WinNT://" + $domain + "/" + $username)
ListAdministrators
Here is a PowerShell script to list Local Users on a remote computer
$strComputer = "XYZ"
$computer = [ADSI]("WinNT://" + $strComputer + ",computer")
$computer.name
$Users = $computer.psbase.children |where{$_.psbase.schemaclassname -eq "User"}
foreach ($member in $Users.psbase.syncroot)
{$member.name}
Here is a PowerShell script to list Local Groups on a remote computer
$strComputer = "XYZ"
$computer = [ADSI]("WinNT://" + $strComputer + ",computer")
$computer.name
$group = $computer.psbase.children |where{$_.psbase.schemaclassname -eq "group"}
foreach ($member in $group.psbase.syncroot)
{$member.name}
This is actually a sister script for my previous post:
Change Administor Password on Remote Machines
and it is merely a one line change to accomplish the task to rename the administrator account on multiple remote machines.
#$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "Machine Name"
$c.Cells.Item(1,2) = "Account Renamed"
$c.Cells.Item(1,3) = "Report Time Stamp"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$intRow = 2
foreach ($strComputer in get-content C:\MachineList.Txt)
{
$c.Cells.Item($intRow,1) = $strComputer.ToUpper()
# Using .NET method to ping test the servers
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $ping.send($strComputer)
if($Reply.status -eq "success")
{
$admin=[adsi]("WinNT://" + $strComputer + "/administrator, user")
#This is the one line change
$admin.psbase.rename("whatever")
$pwage = $admin.passwordage
If($pwage -ne $null)
{
$c.Cells.Item($intRow,2).Interior.ColorIndex = 4
$c.Cells.Item($intRow,2) = "Yes"
}
Else
{
$c.Cells.Item($intRow,2).Interior.ColorIndex = 3
$c.Cells.Item($intRow,2) = "No"
}
}
Else
{
$c.Cells.Item($intRow,2).Interior.ColorIndex = 3
$c.Cells.Item($intRow,2) = "Not Pingable"
}
$c.Cells.Item($intRow,3) = Get-Date
$Reply = ""
$pwage = ""
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
cls
In my previous post, I listed user group membership in AD and now we will visit the other side of the street. Here is a powershell script to list target group members in Active Directory
$root=([ADSI]"").distinguishedName
# You can change Domain Admins to any group interested and of course modify the path
$Group = [ADSI]("LDAP://CN=Domain Admins, CN=Users,"+ $root)
$Group.member
Here is a powershell script to list target user’s group membership in Active Dreictory
$root=([adsi]"").distinguishedName
$ou=[adsi]("LDAP://ou=x,ou=y,ou=z,"+$root)
# here targetCN should be the exact CN for interested user in your AD
$user=$ou.psbase.children.find("cn=tartetCN ")
$groups = $user.memberof
foreach($group in $groups)
{
$strGroup = $group.split(',')[0]
$strGroup = $strGroup.split('=')[1]
$strGroup
}
Here is a PowerShell script to change local administrator (or any account interested) password on a list of remote machines. I am using my friend Don Hite's VB Script as a starting point. So as always my hat off to Don!
$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "Machine Name"
$c.Cells.Item(1,2) = "Password Changed"
$c.Cells.Item(1,3) = "Report Time Stamp"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$intRow = 2
foreach ($strComputer in get-content C:\MachineList.Txt)
{
$c.Cells.Item($intRow,1) = $strComputer.ToUpper()
# Using .NET method to ping test the servers – This is very cool!
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $ping.send($strComputer)
if($Reply.status -eq "success")
{
# This is the Key Part
$admin=[adsi]("WinNT://" + $strComputer + "/administrator, user")
$admin.psbase.invoke("SetPassword", "Whatever1")
#$admin.psbase.CommitChanges() - I am surprised that I don't have to do this!
# If this is for AD account, we could use PasswordLastchanged attribute. But WinNT provider does not #support the PasswordLastChanged attribute!
# I was trying to use passwordage attribute value but somehow I found it give you the value for last time, #may be because there is a delay for this attribute to propagate. So I made an “executive” decision to test #if passwordage is $null – so this may not be 100% accurate.
$pwage = $admin.passwordage
If($pwage -ne $null)
{
$c.Cells.Item($intRow,2).Interior.ColorIndex = 4
$c.Cells.Item($intRow,2) = "Yes"
}
Else
{
$c.Cells.Item($intRow,2).Interior.ColorIndex = 3
$c.Cells.Item($intRow,2) = "No"
}
}
Else
{
$c.Cells.Item($intRow,2).Interior.ColorIndex = 3
$c.Cells.Item($intRow,2) = "Not Pingable"
}
$c.Cells.Item($intRow,3) = Get-Date
$Reply = ""
$pwage = ""
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
cls
$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "Machine Name"
$c.Cells.Item(1,2) = "Ping Status"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$d.EntireColumn.AutoFit($True)
$intRow = 2
$colComputers = get-content C:\Myworkplace\Clientlist1.txt
foreach ($strComputer in $colComputers)
{
$c.Cells.Item($intRow, 1) = $strComputer.ToUpper()
# This is the key part
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $ping.send($strComputer)
if ($Reply.status –eq “Success”)
{
$c.Cells.Item($intRow, 2) = “Online”
}
else
{
$c.Cells.Item($intRow, 2) = "Offline"
}
$Reply = ""
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
Here is a PowerShell script to query ADSI and to get user account properties and report the results in excel. When I wrote this script, there are three huddles(trial and errors) I had to overcome which I added notes here to save you time.
$erroractionpreference = "SilentlyContinue"
$a = New-Object -comobject Excel.Application
$a.visible = $True
$b = $a.Workbooks.Add()
$c = $b.Worksheets.Item(1)
$c.Cells.Item(1,1) = "User"
$c.Cells.Item(1,2) = "UserName"
$c.Cells.Item(1,3) = "Home Directory"
$c.Cells.Item(1,4) = "Home Drive"
$c.Cells.Item(1,5) = "Membership"
$c.Cells.Item(1,6) = "Mail"
$c.Cells.Item(1,7) = "Account Disabled"
$c.Cells.Item(1,8) = "Report Time Stamp"
$d = $c.UsedRange
$d.Interior.ColorIndex = 19
$d.Font.ColorIndex = 11
$d.Font.Bold = $True
$intRow = 2
#You need to pay very close attention to the CN format(or syntax) and it has to be exact especially if you have a , in the cn, and if you are not sure, you could find them in ADSI veiwer (adsiedit.msc) or by doing this: $user=$ou.psbase.children | where {$_.givenname -like “bgates”}
($CNs = get-content C:\Myworkplace\CNs.txt
foreach ($cn in $CNs)
{
Function GetUserInfo
{
# Use DirectoryEntry object from .NET to bind to your AD, Replace with your exact Path here
$ou=new-object directoryservices.directoryentry("LDAP://ou=x,ou=y,dc=whatever1,dc=whatever2,dc=com")
# get the user object and since I am using PowerShell RC2 and I have to use psbase here – MOW has a blog # on this http://mow001.blogspot.com/2006/09/powershell-rc2-and-active-directory.html
$user=$ou.psbase.children.find("cn=$cn")
# Notice here I have to add .Tostring – I believe this has something to do with how the object in ADSI handled
$c.Cells.Item($intRow,1) = $user.name.Tostring()
$c.Cells.Item($intRow,2) = $user.sAMAccountname.Tostring()
$c.Cells.Item($intRow,3) = $user.homeDirectory.Tostring()
$c.Cells.Item($intRow,4) = $user.homedrive.Tostring()
$c.Cells.Item($intRow,5) = $user.memberof.Tostring()
$c.Cells.Item($intRow,6) = $user.mail.Tostring()
if($user.psbase.invokeget('AccountDisabled') -eq $True)
{
$c.Cells.Item($intRow,7).Interior.ColorIndex = 3
$c.Cells.Item($intRow,7) = "Disabled"
}
Else
{
$c.Cells.Item($intRow,7) = "Enabled"
}
}
GetUserInfo
$c.Cells.Item($intRow,8) = Get-date
$intRow = $intRow + 1
}
$d.EntireColumn.AutoFit()
cls
To check if PowerShell is installed use:
HKLM\Software\Microsoft\PowerShell\1 Install ( = 1 )
To check if RC2 or RTM is installed use:
HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-00301) -- For RC2
HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-04309) -- For RTM
Also you could do the following
PS C:\Myworkplace\PS> get-host
Name : ConsoleHost
Version : 1.0.0.0
InstanceId : 2a52c07a-b708-430b-952a-af9f73431b46
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
PS C:\Myworkplace\PS> $host.version
Major Minor Build Revision
----- ----- ----- --------
1 0 0 0
But the above will only give you the host version not the file version and for most people that’s good enough.
In case you are curious, you could do the following
PS C:\Myworkplace\PS> (gcm "$PSHome\PowerShell.exe").FileVersionInfo.ProductVersion
6.0.5429.0
Check out this Technet video presentation about using PowerShell in Exchange Server 2007 – it is a must see!
IT's Showtime.
Ever has a need to open multiple browser at one time and at the mean time “love” PowerShell? Well Looks like PowerShell is going to love you back!
Try save the following script as whatever.ps1 and then in PowerShell console type whatever.ps1 yahoomail yahoofinance hotmail myitforum – that’s normally how I start my day! 
$args | foreach-object {
$ie = new-object -comobject "InternetExplorer.Application"
$ie.visible = $true
$ie.navigate("http://www." + $_ + ".com")
}
Here is a powershell script to display service status on a remote client in a colored webpage and inspired by my friend Don Hite’s VBScript.
$a = new-object -comobject MSScriptControl.ScriptControl
$a.language = "vbscript"
$a.addcode("function getInput() getInput = inputbox(`"Enter Your Computer Name`",`"Computer Name`") end function" )
$strcomputer = $a.eval("getInput")
$ie = new-object -comobject InternetExplorer.Application
$ie.visible = $True
$ie.navigate("About:Blank")
$ie.document.title = "Service Status for $strComputer"
$ie.toolbar = ""
$ie.statusbar = ""
$colServices = [System.ServiceProcess.ServiceController]::GetServices($strComputer)
foreach($svc in $colServices)
{$strHtml = $strHtml + $svc.displayname + "(Status " + $svc.Status + ")" + "</Br>"}
$ie.Document.body.Bgcolor = "MintCream"
$ie.Document.FgColor = "MidnightBlue"
$ie.Document.Body.InnerHTML = $strHtml
It seems your waistline is more important than your weight!
Pot Bellies Point to Heart Risk on Yahoo! Health.
More Posts
Next page »