List ALL properties and subproperties of a variable in Powershell

With one small adjustment, the script in my previous post can be used as a function to list all properties and subproperties of any variable in Windows Powershell. It’s a great way to explore Powershell and create scripts. I used to do the following procedure very often:

$a = Get-Process #For Example
$a
$a[0] | fl *
$a[0].Modules | fl *
etc.

With this function loaded into my profile, this becomes:

$a = Get-Process # For Example
Get-ALLPropertyNames ‘$a’

Here’s the function:

Continue reading

»crosslinked«

List ALL available properties in the VI Toolkit

UPDATE: Fixed the script to also recurse through arrays. It only gets the first item in the array. That’s for a good reason. Else you’ll get millions of items!

Wow! This was quite a challenge. But I did it!
Inspired by my scripts Create a Directory Tree with Powershell and Listing AD Group Members Recursively with Powershell, I responded to a queation in the VI Toolkit Community: “Is it possible to recursively get all the properties of a VI Toolkit object, such as returned by Get-VMHost | Get-View?”

Here is my script. It creates a collection of objects with the property names (full names) and their values (Great for Export-Csv).

Usage: $VMView = Get-VM | Get-View
.\ShowMyVMProperties.ps1 ‘$VMView’

Do not forget the single quotes around the $VMView there. You can use any variable name you like as well as any object from the VI Toolkit.

param([string]$VariableName)

# Function that lists the properties
function Show-Properties
{
Param($BaseName)
If ((Invoke-Expression $BaseName) -ne $null)
{
#Write-Host “Expanding $BaseName”
$Children = (Invoke-Expression $BaseName) | Get-Member -MemberType Property
ForEach ($Child in ($Children | Where {$_.Name -ne “Length” -and $_.Name -notmatch “Dynamic[Property|Type]” -and $_.Name -ne “”}))
{
$NextBase = (“{0}.{1}” -f $BaseName, $Child.Name)
$Invocation = (Invoke-Expression $NextBase)
If ($Invocation)
{
If ($Invocation.GetType().BaseType.Name -eq “Array”)
{
#Write-Host (“{0} is an array.” -f $Child.Name)
# Recurse through subdir
$NextBase = $NextBase + ‘[0]‘
Show-Properties $NextBase
}
ElseIf ($Child.Definition -like “VMware*”)
{
#Write-Host (“{0} is a VMware Object” -f $Child.Name)
# Recurse through subdir
Show-Properties $NextBase
}
Else
{
#Write-Host (“{0} is an endpoint.” -f $Child.Name)
$myObj = “” | Select Name, Value
$myObj.Name = $NextBase
$myObj.Value = $Invocation
$myObj
}
}
Clear-Variable Invocation -ErrorAction SilentlyContinue
Clear-Variable NextBase -ErrorAction SilentlyContinue
}
}
Else
{
Write-Warning “Expand Failed for $BaseName”
}
}

# Actual start of script
If ((Invoke-Expression $VariableName).GetType().BaseType.Name -eq “Array”)
{
$VariableName = $VariableName + ‘[0]‘
}
Show-Properties $VariableName

Finding and Stopping VI Sessions with Powershell

If you have been trying out the VMware VI Toolkit for Windows Powershell, you have probably noticed. You have to disconnect (disconnect-viserver) each session you set up to the VI Server (connect-viserver), or it will linger for eternity (or until the next reboot at least). That’s why I always include a disconnect-viserver command at the end of my VI Toolkit scripts. But what happens in real life: when debugging a script, it hardly ever reaches the end of the script. It will stop at an error or be cancelled by me to fix some bug I notice. I regularly check the Sessions tab in my VI Client and terminate all my idle sessions to keep VI clean and fast. So why not automate that too? Here’s how:

function Get-Session
{
$Global:SI = Get-View ServiceInstance
$Global:SM = Get-View $SI.Content.SessionManager
Return $SM.SessionList
}

function Stop-Session
{
Process
{
ForEach ($Session in $_)
{
If ($Session.Key -ne $SM.CurrentSession.Key)
{
$Key = $session.Key
$SM.TerminateSession($Key)
Write-Host “Session $Key terminated.”
$Key = $null
}
Else
{
Write-Warning “Cannot terminate current session.”
}
}
}
}

The function Get-Session lists the currently active sessions. You can then filter them as you do any collection of objects in Powershell and pipe them to Stop-Session to have them terminated. Note that VI Client sessions appear to create two actual sessions and that the API (and therefore my function) will not allow you to terminate the current session.
Example:

Get-Session | Where { ((Get-Date) – $_.LastActiveTime).TotalHours -ge 8 } | Stop-Session

Enjoy!

Create a Directory Tree with Powershell

I was playing around with PSDrives when I decided to write this script. It recurses through (part of) a PSDrive and shows the items it finds in a simple tree view.
The fun part is that it works on any PSDrive!

  • Show-Tree D:\scripts will show subdirectories and files in a tree;
  • Show-Tree HKCU:\ will show Registry keys and subkeys in a tree;
  • Show-Tree VI:\ will show your VMware Virtual Infrastructure in a tree, if you first create a PSDrive for it.

Here’s how to create a PSDrive for you Virtual Infrastructure:

Connect-VIServer MYVISERVER
$root = Get-Folder -NoRecursion
New-PSDrive -Name VI -PSProvider VIMInventory -Root ‘\’ -Location $root

Creating a full tree takes plenty of time, but you can get a branch of the full tree like so: Show-Tree VI:\MYDATACENTER\host\MYFOLDER\MYCLUSTER, where you replace the caps with your own names. Use vm instead of host to show the Virtual Machines and Templates view instead of the Hosts and Clusters view.
Hugo

Param($BaseDir)

# Function that lists the children of a dir
function Show-TreeItems
{
Param($Location)

# Function that indents to a level i
function Indent
{
Param([Int]$i)
$Global:Indent = $null
For ($x=1; $x -le $i; $x++)
{
$Global:Indent += ” “
}
}

$Children = Get-ChildItem $Location | Sort Name
ForEach ($Child in $Children)
{
Indent $i
“{0}{1}” -f $Indent,$Child
If ($Child.PSIsContainer)
{
# Recurse through subdir
$i++
Show-TreeItems $Child.PSPath
$i– # NOTE THERE SHOULD BE TWO MINUS SIGNS HERE
}
}

}

# Actual start of script
$i = 0
Show-TreeItems $BaseDir

Site Update

PeetersOnline.nl has been updated, restyled, pimped, tricked out… whatever you want to call it.
So, if you are following me via RSS, please come take a look at the new site design.
If you have any remarks or experience any issues, please leave a comment.

So much for visuals. Back to the scripting!
Hugo

Listing AD Group Members Recursively with Powershell

The Quest Active Directory Cmdlets are very useful in getting AD group members. The only thing I was missing, was a -Recursive parameter. So I created this script.

You feed it AD Group Names as a parameter, and it will return a nice tree view of all members and subgroups and their members and so on. Finally, it returns a list of allunique members and their email addresses. You can easily modify the script to include other properties and export the ouput to a csv file.

I hope you like it.

Hugo

Get-MyGroupMembersRecursive (Rename to .ps1)

Modifying vSwitch Offload Policy with Powershell

Of all the vSwitch properties, the Offload Policy settings are the most obscure. You can’t even view them through the GUI. You can see them in the /etc/vmware/esx.conf file, or using the Powershell VI Toolkit, if you know how to use this command:

((Get-VMHostNetwork ESXSERVER | Get-View).NetworkConfig.vSwitch | Where {$_.Name -eq “vSwitch1″}).Spec.Policy.OffloadPolicy

I told you it’s obscure…

Changing the settings is even more difficult, as the method that allows you to do so, requires almost every possible property to be set, even if you don’t want to change it. So, I thought I’d make it a bit more simple. How about the following command:

Set-MyOffloadPolicy -VMHost ESXSERVER -vSwitch “vSwitch1″ -TcpSegmentation Off

All you need is to connect to your VIServer and make sure this function is loaded:

Set-MyOffloadPolicy (rename to .ps1 or copy into your profile)

Hope you like it!

Listing share permissions for remote shares

Now that you can list shares, how about something a bit more challenging?

Let’s take a look at share permissions. I tried using subinacl.exe to get these for a remote share. But it turns out that it does not always give trustworthy results. It showed read permissions for a share with Read and Change permissions. And let’s not mention the single-string, unicode output! What a nightmare!

Then I took one step back and issued the following command:

Get-WmiObject -ComputerName REMOTESERVER -List | Where { $_ -match “share” }

Turns out there is a WMI class called Win32_LogicalShareSecuritySetting that can help out!

Using Get-Member, I found the methods and properties I needed to make this work. And after some googling for the meaning of the AccessMask numbers, I was all done.

I have attached the script. Rename it to .ps1 and dot-source it, or paste it into your profile. Then give this command a try:

Get-MySharePermissions REMOTESERVER SHARENAME

Oh, objects! I love Powershell!

Get-MySharePermissions (rename to .ps1 or copy into profile)

Finding Shares with Powershell

Here’s a handy little function I wrote for enumerating all shares on a remote server:

function Get-MyShares
{
 param([string]$Server)
 $Shares = Get-WmiObject -Class Win32_Share -ComputerName $Server
 $output = @()
 ForEach ($Share in $Shares)
 {
  $fullpath = “\\{0}\{1}” -f $server, $share.name
  Add-Member -MemberType NoteProperty -InputObject $Share -Name FullPath -Value $fullpath
  $output += $Share
 }
 Return $output
}

Note that I am adding an additional property to the default output of the WMI query. It contains the full path to the share in the format \\server\share.

Enjoy!