#  DisplayADSIProviderClasses.pl
#  Example 9.2:
#  ----------------------------------------
#  From "Win32 Perl Scripting: Administrators Handbook" by Dave Roth
#  Published by New Riders Publishing.
#  ISBN # 1-57870-215-1
#
#  This script displays the various classes and properties that an
#  ADSI provider exposes.
#
print "From the book 'Win32 Perl Scripting: The Administrator's Handbook' by Dave Roth\n\n";


use Win32;
use Win32::OLE qw( in );

$Domain = Win32::DomainName();
$ADsPath = "WinNT://$Domain" unless( $ADsPath = shift @ARGV );
if( my $ADSIObject = Win32::OLE->GetObject( $ADsPath ) )
{
  print "Examining the '$ADsPath' ADSI class...\n";
  if( my $DSSchema = Win32::OLE->GetObject( $ADSIObject->{Schema} ) )
  {
    ProcessClass( $DSSchema );
  }
}

sub ProcessClass
{
  my( $DSSchema ) = @_;
  local $PropType;
  # Get the class' parent class...
  my $ParentClass = Win32::OLE->GetObject( $DSSchema->{Parent} );
  # Get this class' properties...
  my %Properties = (
        mandatory   =>  $DSSchema->{MandatoryProperties},
        optional    =>  $DSSchema->{OptionalProperties}
  );
  # Go and get all sub classes that this class may have...
  my $SubClasses = $DSSchema->{Containment};
  $ClassList{$DSSchema->{Name}} = 1;
  print "Class:  $DSSchema->{Name}\n";
  if( scalar @{$SubClasses} )
  {
    $~ = SUBCLASS_HEADER_FORMAT;
    write;
    $~ = SUBCLASS_FORMAT;
    map
    {
      write;
    } @{$SubClasses};
    print "\n";
  }

  $~ = PROPERTY_HEADER_FORMAT;
  write;
  $~ = PROPERTY_FORMAT;

  # Display all properties...
  foreach $PropType ( keys( %Properties ) )
  {
    my $PropList = $Properties{$PropType};
    next unless( scalar @{$PropList} );
    foreach my $PropName ( @{$PropList} )
    {
      local $Property;
      if( $Property = $ParentClass->GetObject( "Property", $PropName ) )
      {
        write;
      }
    }
  }
  print "\n";

  if( scalar @{$SubClasses} )
  {
    foreach my $Class ( @{$SubClasses} )
    {
      my $ADsPath = $DSSchema->{Parent} . "/$Class";
      next if( defined $ClassList{$Class2} );
      if( my $ADSIObj = Win32::OLE->GetObject( $ADsPath ) )
      {
        ProcessClass( $ADSIObj );
      }
    }
  }
  print "\n";
}

format SUBCLASS_HEADER_FORMAT =
  Subclasses   
  ----------------------------
.        
format SUBCLASS_FORMAT =
  @<<<<<<<<<<<<<<<<<<<<<<<<<<
  $_
.        
format PROPERTY_HEADER_FORMAT =
  Property   Name                           Type
  ---------- ------------------------------ -----------
.        
format PROPERTY_FORMAT =
  @<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<
  $PropType, $Property->{Name}, $Property->{Syntax}
.        
