Powershell Retrieving Remote System Time

Compare Local Date and Time to a Remote Computer

This is a rather interesting problem. I was doing a comparison between an audit table and a trace for SQL Server, which was proving to be dificult as I soon realized there was latency as well as the system date’s had an offset. So I turned to my good old friend, Powershell. Powershell has a very nice interface for coding against WMI, which I fully leveraged in this code snippet.

#Server name here. 
$ServerName = <Server Name Here>
#Retreive the localtime of the server. 
$remoteDate = Get-WmiObject -ComputerName $ServerName -Class win32_operatingsystem -Property LocalDateTime
#Converting a WMI time to a standard datetime format. 
$remoteDate = [System.Management.ManagementDateTimeConverter]::ToDateTime($remoteDate.LocalDateTime)

$localDate = Get-Date

#Displaying the difference. 
$remoteDate - $localDate
Advertisement

DirectoryOperationException – The object does not exist.

System.DirectoryService.Protocols Library

This was a very frustrating error. I was able to connect to LDAP through LDAPadmin but not through a program I was creating. “The object does not exist” error occurs, at least in my experience when the credentials you are passing to the server do not authenticate.

In this case I was getting nowhere. Resorting to Wireshark, filtering against port 389, which is the port for LDAP resulted in me seeing a backslash in the credentials being passed as well as the username coming after the organization, which is wrong for my environment.

The resolution was to set the domain to nothing in VB or null in C# in my Net.NetworkCredential object. At the same time moving the organization to the username property.

Dim credLDAP As New Net.NetworkCredential(“cn=username”,”password”, “o=domain”)
does not work, but this does:
Dim credLDAP As New Net.NetworkCredential(“cn=username,o=domain”,”password”, nothing)

Powershell – Top Command

For those of you who love the top command in Linux…

 

function Get-Top{

#######################################

##Get-Top

##

##Written By: John Glasgow

#######################################

<#

.SYNTAX

Get-Top [-delay interval] [-pid pid_number]

 

.SYNOPSIS

Emulates the top command from Linux/Unix.

 

.EXAMPLE

To set delay of 5 seconds.

Get-Top -delay 5

 

.EXAMPLE

To watch a particular process.

Get-Top -pid 4408

#>

$delay = 2

$proc = -1

 

for($i = 0; $i -lt $args.Count; $i += 1){

if( $args[$i] -ilike “-d*” ){

$i++

$delay = $args[$i]

}

if( $args[$i] -ilike “-p*” ){

$i++

$proc = $args[$i]

}

if( $args[$i] -ilike “-q*” ){

$i++

$delay = 0

}

}

 

while ($true){

Clear-Host

if($proc -gt 0){Get-Process | Sort-Object -Descending cpu | Where-Object{ $_.Id -eq $proc } | Format-Table}

else{Get-Process | Sort-Object -Descending cpu | Select-Object -First 20 | Format-Table}

Start-Sleep -Seconds $delay

}

}

Set-Alias top Get-Top

PowerGUI – Remotely Determine if Powershell is Installed

Here is a Node Script to determine if Powershell is installed on a remote computer:

[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.VisualBasic’) | Out-Null
$name = [Microsoft.VisualBasic.Interaction]::Inputbox(“Enter the IP or Name of the server:”)
$pshell = Get-WmiObject Win32_QuickFixEngineering -ComputerName “$($name)” | Where-Object{$_.HotFixID -eq “kb968930”}
if ($pshell -eq $null){Write-Output “Powershell 2.0 is NOT installed.”}
else {Write-Output “Powershell 2.0 IS installed”}

If you found this useful, subscribe.

PowerGUI – Powershell Remote Installed Hotfixes & Patches

Here is a Node Script to get the installed patches or hotfixes on a remote computer:

[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.VisualBasic’) | Out-Null
$name = [Microsoft.VisualBasic.Interaction]::Inputbox(“Enter the IP or Name of the server:”)
Get-WmiObject Win32_QuickFixEngineering -ComputerName “$($name)” | Where-Object{$_.HotFixID -ne “File 1”} | Write-Output

I also have a system monitor to keep track of disk space and CPU/Memory Usage…Click here!

If you found this useful, subscribe.

Powershell Disk Space

If you found this useful, subscribe.

This is a newer, cleaner version of a previous post.

https://refactoringself.wordpress.com/2010/10/11/powergui-using-powershell-to-get-disk-space/

 

# Getting disk information
[System.Object[]]$disks = @()
$Private:wmiDisks = (Get-WmiObject Win32_LogicalDisk | Where-Object {$_.DriveType -eq 3})

foreach ($Private:wmiDisk in $wmiDisks){
$Private:tmp = New-Object -TypeName System.Object
$tmp | Add-Member -Name DeviceID -Value $wmiDisk.DeviceID -MemberType NoteProperty
$tmp | Add-Member -Name FreeSpace -Value $([Math]::Truncate($wmiDisk.FreeSpace / 1GB)) -MemberType NoteProperty
$tmp | Add-Member -Name TotalSpace -Value $([Math]::Truncate($wmiDisk.Size / 1GB)) -MemberType NoteProperty
$disks += $tmp}

I also have made a monitoring system free for your use, here.

 

Powershell System Monitoring

In the next couple days I plan on releasing to you a script and database that you can use to get information about your servers and track them over time. What they do is relatively simple but should help many of you with some very common admin headaches!

Update

It is now here!

 

 

 

Technorati Code QQXYEUN7JHW2

Powershell – How to Remove Array Elements

Normally, to remove array elements you simply assign the elements you want to keep back to the array’s name. What is really happening is the array is getting copied to a new array with the same name like this:

$array = $array[0..($i – 1)] + $array[($i – 1)..$array.Count-1]

So here is something strange that I noticed today. If you are looping through an array, based on the length of the array, and remove an element; the loop will get stuck in an infinite loop. Here is an example:

[string[]]$array = (1..10)

for ($i = 0; $i -lt $array.Count; $i += 1){

$array = $array[0..($i – 1)] + $array[($i – 1)..$array.Count-1]

}

From what I can see, it looks like the $array.Count in argument list for the for loop only gets calculated once. When an element is removed, it can never break out of the loop because the condition never gets satisfied. If you were to do this in VB it would error out, but not in Powershell, this is a possible bug they will have to fix in a later release.

If you found this useful, subscribe.

SQL Server Maintenance Plans vs. Powershell Scripts

I have been working on maintenance plans for some time now and while they are very powerful I am starting to wonder if Powershell might be a better platform to perform my server maintenance. I am starting to lean towards Powershell and here is why. Keep in mind that this is up for debate and I am sure this could stir up some controversy. 

With Powershell it is easier to get access to the OS.  With maintenance plans it gets a little more complicated. Maintenance plans are built for SQL DBAs, not for the person who owns the whole box. Sometimes DBAs have limited access to the server, so for those people Powershell isn’t the best choice. Also if you don’t have a programming background, Powershell might not be for you although you might want to consider it since there are some very simple scripts that can get some serious information to you very quickly, but I digress.

Scripts are highly portable. SSIS packages are as well but you can’t edit them easily without BIDS. Notepad is all you need for Powershell.

I am going to keep you all posted as I am making changes to my scripts.  Once I make a really good script I will post it.

PowerGUI – Using Powershell to get Disk Space

This is a script you can use in PowerGUI as a script node. This handy little script will give you the basic information of your drives so you can figure out if you disks are going to run out of space! I had to make a modification to this script, it works much better now! I apologize to everyone who was using the older script, which works well in Powershell but not PowerGUI.

Note: This will work with your existing credentials.

[System.Reflection.Assembly]::LoadWithPartialName(‘Microsoft.VisualBasic’) | Out-Null
$name = [Microsoft.VisualBasic.Interaction]::Inputbox(“Enter the IP or Name of the server:”)

$drives = gwmi win32_logicaldisk -ComputerName $name | where{ $_.drivetype -eq 3 }
$driveArray = @()
$counter = 0
foreach ($drive in $drives){
$driveArray += New-Object -TypeName System.Object
$driveArray[$counter] | Add-Member -MemberType NoteProperty -Name name -Value $drive.Name
$driveArray[$counter] | Add-Member -MemberType NoteProperty -Name percentfree -Value ([int] [System.Math]::Round(($drive.FreeSpace) / $drive.Size * 100))
$driveArray[$counter] | Add-Member -MemberType NoteProperty -Name sizeGB -Value ([int]($drive.Size / 1Gb))
$driveArray[$counter] | Add-Member -MemberType NoteProperty -Name freespaceGB -Value ([int]($drive.FreeSpace / 1Gb))
$counter +=1
}
$driveArray | Format-Table

A slimmed down version for the Powershell console can be found here: Console Script

I also made a system monitoring script, free for you to use.

If you found this useful, subscribe to my blog.