Get Chitika Premium

With the release of VAS 3.5 last year, there’s been a marked increase in Mac interest and activity for me.  One thing I had to do whilst on-site with an Italian client was give them a way to deploy VAS to 300+ Macs without visiting each machine.  Basically, they needed a scripted way to install an mpkg or dmg file onto the Mac.  In the unix and linux world, this is pretty common.  All of the major vendors have clear documentation on how to do this.

However, Apple’s approach is always through the GUI.  And finding an example on how to do this from the command line took quite some time.  So to save someone the trouble in the future, here is the script I sent over to the client.  Since writing it in March, I’ve had at least a half dozen requests for it inside of Quest, so it made sense to put this out there publicly.  And while this one is specific to VAS (extra bonus if you’re running VAS on Mac), it should work for most Mac packages, and should only require a minor tweaking.

Note: the only requirement is that some sort of remote login option be available – there’s simply no point to using this script if you’re going to sit in front of a Mac inside the terminal window.  The way to do this is to enable ‘Remote Login,’ which is off by default, and that will enable ssh on the mac so you can connect to it with something like Putty.

As an added bonus, here’s a 6 minute video showing this being done: http://www.idmwizard.com/quest/vas35_mac_install_manual/index.html

########################################################################
# install the mac client using the command line
# first, mount the dmg file
hdiutil attach /<somelocation>/VAS-3.5.0.33.dmg

# that should create a new volume which we can cd to
cd /Volumes/VAS-Installer 
# this is the actual install of VAS onto the machine
sudo /usr/sbin/installer -pkg VAS.mpkg/ -target / 
# install is done, so we can now unmount the dmg - change directories first, though!
cd /opt/quest/bin
hdiutil detach /Volumes/VAS-Installer 
# join the machine to the AD domain
# sudo /opt/quest/bin/vastool -u <aduser> join -c "ou=apple,ou=xxx,ou=yyyy,dc=root,dc=dom" root.dom 
# better yet, join the machine with a pre-created account
# HOST=`hostname | awk -F. '{print $1}'`; /opt/quest/bin/vastool -u host/ -w $HOST join -f -n ${HOST}.root.dom root.dom
# update DNS record in AD (DDNS is in the VAS package install)
# but if your mac is not using dhcp, I don't think this is run
sudo /opt/quest/sbin/dnsupdate <IP> 
# since macs are 'personal'
# there's usually 1 user on the machine - and you probably already have
# 1 AD user ready to use
# so copy the default user to the new AD user
# (this may take some time depending on the folder size)
sudo cp -R /Users/<localuser> /Users/<ADUser>
# reown all the files to the AD users (<ADGroup> can also be a local group)
sudo chown -R <ADUser>:<ADGroup> /Users/<ADUser> 
# later, when everyone is happy, and it is all working, run this to get rid of the local user profile
sudo rm -rf /Users/<localuser>
Get Chitika eMiniMalls

I found this rattling around in my email from July 16th.  Its a quick 1 liner to add every unregistered GPO into GPM:

foreach($unregObj in ($VCManager.GetGpos($VCManager.GetDomainNames())  |
   Where-Object -FilterScript {$_.Registered -eq $False} ))
   {$VCManager.Register("00000000-0000-0000-0000-000000000000", $unregObj,
   "Registering automatically via PoSh script", 1.0);}

You do need to prefix this with something like:

& 'C:\Program Files\Quest Software\Quest Group Policy Manager\QGPMInit.ps1' -computerName localhost -portNumber 40200

but that’s what happens when there’s no PoSh cmdlets available. Hope it helps . . .

Here’s a list of some other recorded demos that are currently residing on www.idmwizard.com, but tucked away.  Instead of keeping the links to myself, I figured it would be easier to post them all up.  Most do not have audio so don’t be alarmed.  Enjoy.

First, some Defender demos – there is no audio on these and the titles should be self explanatory:

Defender
http://www.idmwizard.com/quest/Defender/1_Initial_Installation/index.html
http://www.idmwizard.com/quest/Defender/2_Server_and_Token_Licensing/index.html
http://www.idmwizard.com/quest/Defender/3_Initial_Setup/index.html
http://www.idmwizard.com/quest/Defender/4_Admin_Token_Assignment/index.html
http://www.idmwizard.com/quest/Defender/5_Reporting_Installation/index.html
http://www.idmwizard.com/quest/Defender/6_Self_Service_Site_Installation/index.html
http://www.idmwizard.com/quest/Defender/7_User_Self_Service_Token_Assignment/index.html
http://www.idmwizard.com/quest/Defender/8_User_Radius_Login/index.html
http://www.idmwizard.com/quest/Defender/9_Defender_User_and_Authentication_Reporting/index.html
http://www.idmwizard.com/quest/Defender/10_Desktop_Token_Installation/index.html
http://www.idmwizard.com/quest/Defender/11_Desktop_Token_User_Activation/index.html
http://www.idmwizard.com/quest/Defender/12_Desktop_Token_Usage/index.html
http://www.idmwizard.com/quest/Defender/13_GINA_Installation_and_Logon/index.html
http://www.idmwizard.com/quest/DefenderDesktopToken/index.html

Next, are some demos of Quest’s ESSO product.  The first one is pretty quick, and has no audio:
http://www.idmwizard.com/quest/esso_personal_gmail/index.html

This next one shows integration between Quest’s ESSO, and the ActiveRoles Server Quick Connect module where a user is created from a CSV file and then the same user logs into Windows, registers with ESSO and is able to get SSO to the app afterwards:
http://www.idmwizard.com/quest/QARS-QC-and-ESSO/QARS-QC-and-ESSO.html

There are then a bunch of VAS videos, again with no audio:
http://www.idmwizard.com/quest/vas/vas35-01-preflight/index.html
http://www.idmwizard.com/quest/vas/vas35-02-install_and_join/index.html
http://www.idmwizard.com/quest/vas/vas35-03-installation_of_quest_ssh_and_getting_sso_through_it/index.html
http://www.idmwizard.com/quest/vas/vas35-04-unix_enable_user_and_group-password_change-sso_via_ssh/index.html
http://www.idmwizard.com/quest/vas/vas35-05-sudo_group_policy_usage_and_config/index.html
http://www.idmwizard.com/quest/vas/vas35-06-file_copy_policy_with_replacement_macro/index.html
http://www.idmwizard.com/quest/vas/vas35-07-access_controls_via_user_files/index.html
http://www.idmwizard.com/quest/vas/vas35-08-access_controls_via_windows_group_policy/index.html
http://www.idmwizard.com/quest/vas/vas35-09-self_enrollment-automatic_local_to_AD_mapping/index.html
http://www.idmwizard.com/quest/vas/vas35-10-installing_vasyp_proxy-getting_yp_maps_from_AD/index.html
http://www.idmwizard.com/quest/vas/vas35-11-using_the_nis_editor/index.html
http://www.idmwizard.com/quest/vas/vas35-12-importing_a_new_nis_map_via_windows/index.html
http://www.idmwizard.com/quest/vas/vas35-13-importing_a_new_nis_map_via_unix_nisedit/index.html
http://www.idmwizard.com/quest/vas/vas35-14-importing_and_enabling_users_with_vastool_load/index.html

People often have questions on what the VAS install looks like on the mac – here are 2 videos of that:
http://www.idmwizard.com/quest/vas35_mac_install/index.html
http://www.idmwizard.com/quest/vas35_mac_install_manual/index.html

Here is VAS’ self-enrollment feature on Solaris 10:
http://www.idmwizard.com/quest/Sol10-VASSelfEnrollment/Sol10-VASSelfEnrollment.html

Barry G also did some recordings for the Java Single Sign-On Product, VSJ here:
http://www.idmwizard.com/quest/vsj/index.html
http://www.idmwizard.com/quest/VSJ-ADFSFlash/VSJ-ADFS/index.html
http://www.idmwizard.com/quest/vsj_PetStore/index.html

(I particularly like Petstore since it was my idea – :D )

Paul H recorded a really slick (but poor in audio) demo of using Quest InSync to reset a Lotus Notes password (including the notes.id file!):

http://www.idmwizard.com/quest/NotesQPMandInSync.avi

Finally, there’s a pretty long (30 minute) video of configuring Webthority with a fictitious site called ‘SkySurf.’  This was done for internal consultants, but may be helpful if you’re looking to see how to configure Webthority:
http://www.idmwizard.com/quest/WebthoritySkySurf/index.html

So in the never ending GPM project, a new requirement came about recently.  It was a report to show the current state of the GPOs within Quest Group Policy Manager before any of the other work is done.  I wound up dubbing the report a ‘pre-flight’ report since we have one already for VAS and its a name that Ross J came up with a few years at another company he and I worked at. 

The first pre-flight report, which just listed every GPO and some info, was done in about 10-15 minutes during the meeting with the client.  However, they also pointed out that there may be many, many GPOs, and they would like to pare the list down to a specific subset of GPOs.  Of course, that proved a little more challenging but I managed to do it  in short order.  So now the script takes in the file path of a CSV and assumes GPOName is the column name with all the GPOs listed.

So, without further ado, here is the preliminary script:

########################################################################################################################################
#
# In an ideal world, this would be a cmdlet called:
#    Preflight-QGPO GPOName [-GPMServer] [-GPMPort] [-GPOListCSV]
#
########################################################################################################################################

Set-ExecutionPolicy Unrestricted;

########################################################################################################################################
# the next section is all hard coded variables which need to be set to script parameters
########################################################################################################################################
# set this param to $true to start taking in command line arguments
$useParams = $true;

if ($useParams)
{
 # Which GPM Server to export from
 $GPMHostname = $args[0];
 
 # Which GPM Server port to use
 $GPMPort = $args[1];
 
 # the location of a CSV file with a list of specified GPOs
 $GPOListCSV = $args[2];
}
else
{
 # Which GPM Server to export from
 $GPMHostname = "localhost";
 
 # Which GPM Server port to use
 $GPMPort = 40200;
 
 # the location of a CSV file with a list of specified GPOs
 $GPOListCSV = "";
# $GPOListCSV = "C:\GPMScripts\GPMPreflight\PreflightGPOs.csv";
}

function OutputGPOSettings ($p_currentGPO)
{
  $gpoName = $p_currentGPO.Name;
  $gpoVersion = $currentGPO.Version;
  $gpoStatus = $currentGPO.Status;
  $gpoLive = $currentGPO.HasLive;
  $gpoTrustee = $currentGPO.Trustee;
  $gpoApprovalRequired = $currentGPO.ApprovalsRequired;
  $gpoApprovalReceived = $currentGPO.ApprovalsReceived;
  
  Write-Output "GPO $iCounter : '$gpoName' - the most current version is $gpoVersion ";
  Write-Output "   The current status is $gpoStatus "
 # not quite sure how useful this is - it is basically live/not live indicator - but is not for the most current version
 # Write-Output "   Is a version of this GPO live ? $gpoLive ";
 
  if (($gpoStatus -eq $statusCheckedOut) -or ($gpoStatus -eq $statusPending) -or ($gpoStatus -eq $statusPendingDeployment ))
  {
   Write-Output "   The current user is: $gpoTrustee ";
   Write-Output "   The approval count required? $gpoApprovalRequired ";
   Write-Output "   The approval count received? $gpoApprovalReceived ";
  }
    
  Write-Output "";
}
#############################################################################################################
# include the GPM stuff - redirected to $null to avoid output to logfile
& 'C:\Program Files\Quest Software\Quest Group Policy Manager\QGPMInit.ps1' -computerName $GPMHostname -portNumber $GPMPort > $null

#valid GPO status for import operation are Available or Check-out
$statusAvailable = [Quest.Avalanche.Enums.StatusType]::Available;
$statusCheckedOut = [Quest.Avalanche.Enums.StatusType]::CheckedOut;
$statusDeleted = [Quest.Avalanche.Enums.StatusType]::Deleted;
$statusError = [Quest.Avalanche.Enums.StatusType]::Error ;
$statusErrorNoWorkingCopy = [Quest.Avalanche.Enums.StatusType]::ErrorNoWorkingCopy ;
$statusPending = [Quest.Avalanche.Enums.StatusType]::Pending ;
$statusPendingDeployment = [Quest.Avalanche.Enums.StatusType]::PendingDeployment ;
$statusUnregistered = [Quest.Avalanche.Enums.StatusType]::Unregistered ;

Write-Output "----------------------------";
Write-Output "Beginning Preflight Check of GPM Server '$GPMHostname' on port $GPMPort ";

$iCounter = 0;

if (($GPOListCSV -eq "") -or ($GPOListCSV -eq $null))
{
 # loop through all the objects in the data set and find the policy we want
 foreach($currentGPO in $VCManager.GetControlledObjects("GPO"))
 {
  $iCounter = $iCounter + 1;
  OutputGPOSettings $currentGPO;
 }
}
else
{
 # bring the file
 $GPOList = Import-Csv $GPOListCSV;

 # loop through all the objects in the data set and find the policy we want
 :GPOLoopCSV foreach($currentGPO in $VCManager.GetControlledObjects("GPO"))
 {
  foreach ($GPOName in $GPOList)
  {
   if ($currentGPO.Name -eq $GPOName.GPOName )
   {
    $iCounter = $iCounter + 1;
    OutputGPOSettings $currentGPO;
   }
  }
 }
}

if ($foundGPO -eq $false)
{
 Write-Output "No GPO named '$gpoName' was found.";
}
Write-Output "Preflight Completed";
Write-Output "----------------------------"; 

I just got an Amazon Kindle, and think its fantastic. However, I’m now torn on what to do with 1 particular book;  Infinite Jest by David Foster Wallace.  The reason is that its a massive book (1100 pages) and I am on page 20.  Should I re-purchase it on the Kindle? The Kindle seems ideal for it, yet I don’t want to spend another $10 on a book I already own.  If I don’t, I doubt I’ll actually get to finish it as I have very little time to read outside riding the train, and the book is just too big to carry around.  Plus, I have 12+ hours of train time coming up this week . . .

(This post was written a while back and has been held up in drafts)

Yesterday (29-5-2009), I was a customer that had 400 users, yet 1,300 active accounts in AD.  And these were not stray/orphaned accounts, but those used for actual services.  One thing they’re not aware of is a new type of object in AD called that Managed Service Accounts.  Regardless, even having that many accounts for so few users is alarming.

They definitely need a better management strategy for managing all those accounts because there’s simply no way to properly keep up with this accounts.  We’ll be working with them in the coming months to help them deploy out Quest ActiveRoles Server to start getting some of this under control and I’m sure it will be a sea change for them once they get a handle on that tool.  I’ll try and keep this site posted on what they do.

I had a pre-release (dare I say “beta”) of this video, and some have shared the links already, but I’ve completed the 10 minute epic that is called “Quest For Password Management.”  The video is rendering and uploading now, and should be up by 11:30 AM GMT.  Its actually a video showing 3 of Quest’s Identity Management products; Quest Password Manager, Quest Defender and Quest Webthority.  Note that Webthority is now part of Defender, and we’re sure to change the name in the future.

Anyway, the recording can be found here:

http://www.idmwizard.com/quest/QuestForPasswordManagement/QuestForPasswordManagement.html

Techie sidenote: The thing that took the longest? Setting up a CA (Certificate Authority).  Now, you’re probably going to ask yourself, “why on earth do I need a CA to do password management?”  And the answer is “you don’t.”  However, if you wish to perform an AD password change, its best to do it over LDAP-S (port 636) rather than plain LDAP (port 389).  And in trying to set this up in Webthority, I swore I found a bug (yes, even Quest products have bugs from time to time).  But it turns out that I just wasn’t configuring the CA properly, and it took our fine support people to point out that I simply didn’t know what I was doing.  In fact, I’m told there will be a support KB article on the topic shortly.  I’ll keep you posted.

Back when I was a dev manager, a site appeared that really intrigued me: Rent A Coder.  I’ve been keeping tabs on for a while now, and finally joined up.  I’m actually surprised its not taken on more prominence, but I do see quite a bit of activity on it.  The most interesting stat is that they have plateaued to having on 5-6% new buyers, and 94%+ of the work is done for repeat customers.

Quick primer on how RAC works: Buyers post up requirements for a project, and developers bid on them.  Once a bid is accepted, the payment for the project is put into an escrow account, and the developer is paid from the account once the project is delivered and tested.  RAC acts as the third party to both buyers and sellers, taking a 15% fee for their services.  Its kind of like ebay for dev projects.

Anyway, I really think this sort of thing is not used enough.  Just the work I do, day to day, mirrors this sort of task-oriented approach.  And if you have a solid enough set of requirements, you should be able to farm out discrete ‘units’ of work and just piece them together.

(note: funny that this post languished in my Drafts for over a month – I really need to check this more often)

Still plodding through the GPO scripting through Quest Group Policy Manager given all the other things I have going on but I cranked this out last week quickly to meet a quick checklist item. As the comments in the code say, “In an ideal world, this would be a cmdlet called Delete-QGPO. “  The only change you need to make is to change the $useParams value to $true to start using it like a cmdlet and feed it the params specified.  As with all things PowerShell, the intent is to call this on 1 object (a GPO) and if you want to use it on a set of objects, get that list, and pipe it in, like so:

import-csv deletelist.csv | % {& Delete-QGPO.ps1 $_.GPOName $_.GPMServer $_.ApprovalRequired}

That is it.  Now for all the code . . .

#############################################################################################################
#
# In an ideal world, this would be a cmdlet called:
#    Delete-QGPO GPOName [-GPMServer] [-GPMPort] [-ApprovalRequired]
#
#############################################################################################################
Set-ExecutionPolicy Unrestricted;
#############################################################################################################
# the next section is all hard coded variables which need to be set to script parameters
#############################################################################################################
$useParams = $false;
if ($useParams)
{ 
 # define the GPO name, which is what people will probably know it as – this can be an argument to a script later
 $gpoName = $args[0];
 # Which GPM Server to export from
 $GPMHostname = $args[1];
 $GPMPort = $args[2];
 
 $ApprovalRequired = $args[3];
}
else
{
 # Which GPM Server to export from
 $GPMHostname = "localhost";
 
 $GPMPort = 40200;
 
 # define the GPO name, which is what people will probably know it as – this can be an argument to a script later
 $gpoName = "Test Policy";
 
 $ApprovalRequired = "no";
}
#############################################################################################################
& 'C:\Program Files\Quest Software\Quest Group Policy Manager\QGPMInit.ps1' -computerName $GPMHostname
$foundGPO = $false ;
# loop through all the objects in the data set and find the policy we want
foreach($currentGPO in $VCManager.GetControlledObjects("GPO") |
      Where-Object {$_.Name -eq $gpoName})
{
 $foundGPO = $true;
 
 # count the number of deployed versions
 $counter1 = 0;
 
 $DeleteGPO = $false;
 
 # check out the GPO so we can edit it
 # you can discard the contents returned since we want a previous version
 $VCManager.Delete($currentGPO.VCId, "Deleting GPO - bye bye");
 Write-Output "Requesting approval to delete GPO $gpoName";
 if ($ApprovalRequired.ToUpper().Substring(0,1) -eq "N")
 {
  $VCManager.Approve($currentGPO.VCId, "Requesting Approval");
  $VCManager.Deploy($currentGPO.VCId, "Deploying (actually deleting) GPO")
  Write-Output "GPO $gpoName deleted";
 }
}
if ($foundGPO -eq $false)
{
 Write-Output "GPO $gpoName not found"
}

I also put together a doc this week that was off the beaten path.  And what was different was not the content but the presentation.  It was a 4-5 page doc, but the guy reading it doesn’t tolerate emails that go ‘below the fold.’  So right after the short summary/intro was a link that said ‘Click here to go to the conclusion.’  So our 30 minute chat had him read the intro, conclusion, and then look at the details last.