none
Script to retreive information from a text file

    Question

  • Hi,

    I am in new to the scripting world and I am looking to create a script which can extract data from a text file.

    for example :- I have a text file which has ipconfig information of about 500 servers, I need to take out the Host names and DNS server information from it. Following is an example of text in the file.

    Remote Windows IP Configuration v. 1.0.2 by Morten Skrubbeltrang

            Host Name . . . . . . . . . . . . : AEDUB001

            Physical Address. . . . . . . . . : 00:1D:09:05:54:69
            DHCP Enabled. . . . . . . . . . . : False
            IP Address. . . . . . . . . . . . : 10.252.5.4
            Subnet Mask . . . . . . . . . . . : 255.255.255.224
            Default Gateway . . . . . . . . . : 10.252.5.1
            DNS Servers . . . . . . . . . . . : 10.252.5.4
                                                10.244.237.12
            Primary WINS Server . . . . . . . : 10.244.237.12
            Secondary WINS Server . . . . . . : 10.244.236.234

     

    This is informaiton of one computer, similarly I have information of 500 computers. I need to extract the Host Name and DNS Servers ip address from this file. I have gone through the below mentioned technet which gives information about how to create a text file, write to a text file, how to open a text file and how to read from a text file, however I couldn't realy use that information for my purpose.

    http://technet.microsoft.com/en-us/library/ee176977.aspx

    Any help would be highly appreciated.

    Wednesday, June 27, 2012 11:12 AM

Answers

All replies

  • This Poweshell "script" will extract just the Host name and DNS servers from your text file:

    gc test.txt | ? { $_ -match 'Host Name|DNS Servers|^\s+[\.|\d]+$'}

    Wednesday, June 27, 2012 11:34 AM
  • An ordinary console command will do the trick:

    findstr /i "host name dns" test.txt

    Wednesday, June 27, 2012 11:51 AM
  • An ordinary console command will do the trick:

    findstr /i "host name dns" test.txt


    Notice that the DNS servers are on two lines.  Your code only takes the first line of the DNS servers entry.

    Grant Ward, a.k.a. Bigteddy

    Wednesday, June 27, 2012 12:09 PM
  • for /f "tokens=16 delims= " %i in ('type sourcefile.txt ^|findstr /i "host name" ^| findstr /V "Ethernet"') do; echo %i >> yourlogfile.txt
    for /f "tokens=14 delims= " %i in ('type sourcefile.txt ^|findstr /i "dns servers"') do; echo %i >> yourlogfile.txt


    If you find this post helpful, spend a second to vote up. Smoking~~


    • Edited by SuperUzer Wednesday, June 27, 2012 1:54 PM
    Wednesday, June 27, 2012 1:53 PM
  • But the question is why to keep it all in a text file? dont you prefer to generate all servers addresses dynamicly?


    If you find this post helpful, spend a second to vote up. Smoking~~

    Wednesday, June 27, 2012 1:59 PM
  • for /f "tokens=16 delims= " %i in ('type sourcefile.txt ^|findstr /i "host name" ^| findstr /V "Ethernet"') do; echo %i >> yourlogfile.txt
    for /f "tokens=14 delims= " %i in ('type sourcefile.txt ^|findstr /i "dns servers"') do; echo %i >> yourlogfile.txt

    Counting spaces between dots seems a rather fragile way of extracting strings, especially for SuperUzer . . .
    Wednesday, June 27, 2012 8:37 PM
  • Notice that the DNS servers are on two lines.  Your code only takes the first line of the DNS servers entry.


    Grant Ward, a.k.a. Bigteddy

    Indeed. This batch file gets around this problem but is nowhere near as elegant as your PowerShell solution. There are lots of severe limitations in batch files . . .

    @echo off
    findstr /i "Host Name" test.txt
    set DNS=0
    for /F "delims=" %%a in (test.txt) do call :sub %%a
    goto :eof

    :Sub
    set Line=%*
    if %DNS% EQU 1 (
      echo                                     %Line%
      set DNS=2
    )
    if not "%Line%"=="%Line:DNS=xxx%" (
      set DNS=1
      echo %Line%
    )

    Wednesday, June 27, 2012 8:39 PM
  • output of ipconfig is the same since jurasic, including the dots. so why not to count them?

    btw, yes. PS is much more elegant


    If you find this post helpful, spend a second to vote up. Smoking~~

    Wednesday, June 27, 2012 9:07 PM
  • I know the question is with regards to parsing a text file, but if you are trying to just get NIC config info for network attached machines, you could use WMI instead of parsing a text file. The data will be more current, and the properties are easy to filter to generate a report. For example, I wrote the following function to get a list of NICs and their associated configs from a remote machine via WMI. (requires admin priv on the target machine) Hope this helps!

    calling example:

    get-nicinfo -strcomputer computername

    Function get-NICInfo($strComputer){
    
    $colNICInfo = @()
    $colNetworkAdapters = get-wmiobject -query "Select * From Win32_NetworkAdapter Where NetConnectionStatus IS NOT NULL and ServiceName !='NIC1394'" -Namespace "root\cimv2" -ComputerName $strComputer
    $colNetworkAdapters | %{
    	$objNIC = New-Object System.Object
    	$objNIC | Add-Member -type scriptmethod -Name "Disable" -Value {$this.Win32_NetworkAdapter.Disable()}
    	$objNIC | Add-Member -type scriptmethod -Name "Enable" -Value {$this.Win32_NetworkAdapter.Enable()}
    	$objNIC | Add-Member -type scriptmethod -Name "ReleaseDHCPLease" -Value {$this.Win32_NetworkAdapterConfiguration.ReleaseDHCPLease()}
    	$objNIC | Add-Member -type scriptmethod -Name "RenewDHCPLease" -Value {$this.Win32_NetworkAdapterConfiguration.RenewDHCPLease()}
    	$objNIC | Add-Member -type scriptmethod -Name "SetDNSServerSearchOrder" -Value {$this.Win32_NetworkAdapterConfiguration.RenewDHCPLease()}
    	$objNIC | Add-Member -type noteproperty -Name "Win32_NetworkAdapter" -Value $_
    	$objNIC | Add-Member -type noteproperty -Name "Win32_NetworkAdapterConfiguration" -Value (get-wmiobject -query ("Associators of {Win32_NetworkAdapter.DeviceID='" + $_.DeviceID + "'} WHERE RESULTCLASS = Win32_NetworkAdapterConfiguration") -Namespace "root\cimv2" -ComputerName $strComputer)
    	$objNIC | Add-Member -type scriptproperty -Name "MACAddress" -Value {$this.Win32_NetworkAdapter.MACAddress}
    	$objNIC | Add-Member -type scriptproperty -Name "AdapterType" -Value {$this.Win32_NetworkAdapter.AdapterType}
    	$objNIC | Add-Member -type scriptproperty -Name "AdapterCaption" -Value {$this.Win32_NetworkAdapter.Caption}
    	$objNIC | Add-Member -type scriptproperty -Name "ConfigCaption" -Value {$this.Win32_NetworkAdapterConfiguration.Caption}
    	$objNIC | Add-Member -type scriptproperty -Name "ConfigDescription" -Value {$this.Win32_NetworkAdapterConfiguration.Description}
    	$objNIC | Add-Member -type scriptproperty -Name "AdapterDescription" -Value {$this.Win32_NetworkAdapter.Description}
    	$objNIC | Add-Member -type scriptproperty -Name "DeviceID" -Value {$this.Win32_NetworkAdapter.DeviceID}
    	$objNIC | Add-Member -type scriptproperty -Name "Manufacturer" -Value {$this.Win32_NetworkAdapter.Manufacturer}
    	$objNIC | Add-Member -type scriptproperty -Name "MaxSpeed" -Value {$this.Win32_NetworkAdapter.MaxSpeed}
    	$objNIC | Add-Member -type scriptproperty -Name "Name" -Value {$this.Win32_NetworkAdapter.Name}
    	$objNIC | Add-Member -type scriptproperty -Name "NetConnectionID" -Value {$this.Win32_NetworkAdapter.NetConnectionID}
    	$objNIC | Add-Member -type scriptproperty -Name "NetEnabled" -Value {$this.Win32_NetworkAdapter.NetEnabled}
    	$objNIC | Add-Member -type scriptproperty -Name "ProductName" -Value {$this.Win32_NetworkAdapter.ProductName}
    	$objNIC | Add-Member -type scriptproperty -Name "AdapterServiceName" -Value {$this.Win32_NetworkAdapter.ServiceName}
    	$objNIC | Add-Member -type scriptproperty -Name "SpeedInMegabitPerSec" -Value {$this.Win32_NetworkAdapter.Speed/1000000}
    	$objNIC | Add-Member -type scriptproperty -Name "DefaultIPGateway" -Value {$this.Win32_NetworkAdapterConfiguration.DefaultIPGateway}
    	$objNIC | Add-Member -type scriptproperty -Name "DHCPLeaseObtained" -Value {$this.Win32_NetworkAdapterConfiguration.ConvertToDateTime($this.Win32_NetworkAdapterConfiguration.DHCPLeaseObtained)}
    	$objNIC | Add-Member -type scriptproperty -Name "DHCPLeaseExpires" -Value {$this.Win32_NetworkAdapterConfiguration.ConvertToDateTime($this.Win32_NetworkAdapterConfiguration.DHCPLeaseExpires)}
    	$objNIC | Add-Member -type scriptproperty -Name "DHCPServer" -Value {$this.Win32_NetworkAdapterConfiguration.DHCPServer}
    	$objNIC | Add-Member -type scriptproperty -Name "DHCPEnabled" -Value {$this.Win32_NetworkAdapterConfiguration.DHCPEnabled}
    	$objNIC | Add-Member -type scriptproperty -Name "StaticIP" -Value {!($this.Win32_NetworkAdapterConfiguration.DHCPEnabled)}
    	$objNIC | Add-Member -type scriptproperty -Name "DNSDomain" -Value {$this.Win32_NetworkAdapterConfiguration.DNSDomain}
    	$objNIC | Add-Member -type scriptproperty -Name "DNSEnabledForWINSResolution" -Value {$this.Win32_NetworkAdapterConfiguration.DNSEnabledForWINSResolution}
    	$objNIC | Add-Member -type scriptproperty -Name "DNSHostName" -Value {$this.Win32_NetworkAdapterConfiguration.DNSHostName}
    	$objNIC | Add-Member -type scriptproperty -Name "DNSServerSearchOrder" -Value {$this.Win32_NetworkAdapterConfiguration.DNSServerSearchOrder}
    	$objNIC | Add-Member -type scriptproperty -Name "IPAddress" -Value {$this.Win32_NetworkAdapterConfiguration.IPAddress}
    	$objNIC | Add-Member -type scriptproperty -Name "IPEnabled" -Value {$this.Win32_NetworkAdapterConfiguration.IPEnabled}
    	$objNIC | Add-Member -type scriptproperty -Name "IPSubnet" -Value {$this.Win32_NetworkAdapterConfiguration.IPSubnet}
    	$objNIC | Add-Member -type scriptproperty -Name "ConfigMACAddress" -Value {$this.Win32_NetworkAdapterConfiguration.MACAddress}
    	$objNIC | Add-Member -type scriptproperty -Name "ConfigServiceName" -Value {$this.Win32_NetworkAdapterConfiguration.ServiceName}
    	$objNIC | Add-Member -type scriptproperty -Name "WINSPrimaryServer" -Value {$this.Win32_NetworkAdapterConfiguration.WINSPrimaryServer}
    	$objNIC | Add-Member -type scriptproperty -Name "WINSSecondaryServer" -Value {$this.Win32_NetworkAdapterConfiguration.WINSSecondaryServer}
    	$objNIC | Add-Member -type scriptproperty -Name "InterfaceIndex" -Value {$this.Win32_NetworkAdapterConfiguration.InterfaceIndex}
    	$objNIC | Add-Member -type scriptproperty -Name "Index" -Value {$this.Win32_NetworkAdapterConfiguration.Index}
    	$objNIC | Add-Member -type scriptproperty -Name "TCPIPNetbiosOptions" -Value `
    	{
    	[hashtable]$MAP_TCPIPNetbiosOptions = @{
    	0 = "EnableNetbiosViaDhcp";
    	1 = "EnableNetbios";
    	2 = "DisableNetbios";
    	}
    	$MAP_TCPIPNetbiosOptions.([int]$($this.Win32_NetworkAdapterConfiguration.TCPIPNetbiosOptions))
    	
    	}
    	$objNIC | Add-Member -type scriptproperty -Name "StatusInfo" -Value `
    	{
    	[hashtable]$MAP_StatusInfo = @{
    	1 = "Other";
    	2 = "Unknown";
    	3 = "Enabled";
    	4 = "Disabled";
    	5 = "Not Applicable";}
    	$MAP_StatusInfo.([int]$($this.Win32_NetworkAdapter.StatusInfo))
    	}
    	$objNIC | Add-Member -type scriptproperty -Name "SystemName" -Value {$this.Win32_NetworkAdapter.SystemName}
    	$objNIC | Add-Member -type scriptproperty -Name "TimeOfLastReset" -Value {$this.Win32_NetworkAdapter.ConvertToDateTime($this.Win32_NetworkAdapter.TimeOfLastReset)}
    	$objNIC | Add-Member -type scriptproperty -Name "ConfigManagerErrorCode" -Value `
    	{
    	[hashtable]$MAP_ConfigManagerErrorCode = @{
    	0 = "Device is working properly.";
    	1 = "Device is not configured correctly.";
    	2 = "Windows cannot load the driver for this device.";
    	3 = "Driver for this device might be corrupted, or the system may be low on memory or other resources.";
    	4 = "Device is not working properly. One of its drivers or the registry might be corrupted.";
    	5 = "Driver for the device requires a resource that Windows cannot manage.";
    	6 = "Boot configuration for the device conflicts with other devices.";
    	7 = "Cannot filter.";
    	8 = "Driver loader for the device is missing.";
    	9 = "Device is not working properly. The controlling firmware is incorrectly reporting the resources for the device.";
    	10 = "Device cannot start.";
    	11 = "Device failed.";
    	12 = "Device cannot find enough free resources to use.";
    	13 = "Windows cannot verify the device's resources.";
    	14 = "Device cannot work properly until the computer is restarted.";
    	15 = "Device is not working properly due to a possible re-enumeration problem.";
    	16 = "Windows cannot identify all of the resources that the device uses.";
    	17 = "Device is requesting an unknown resource type.";
    	18 = "Device drivers must be reinstalled.";
    	19 = "Failure using the VxD loader.";
    	20 = "Registry might be corrupted.";
    	21 = "System failure. If changing the device driver is ineffective, see the hardware documentation. Windows is removing the device.";
    	22 = "Device is disabled.";
    	23 = "System failure. If changing the device driver is ineffective, see the hardware documentation.";
    	24 = "Device is not present, not working properly, or does not have all of its drivers installed.";
    	25 = "Windows is still setting up the device.";
    	26 = "Windows is still setting up the device.";
    	27 = "Device does not have valid log configuration.";
    	28 = "Device drivers are not installed.";
    	29 = "Device is disabled. The device firmware did not provide the required resources.";
    	30 = "Device is using an IRQ resource that another device is using.";
    	31 = "Device is not working properly. Windows cannot load the required device drivers.";
    	}
    	$MAP_ConfigManagerErrorCode.([int]$($this.Win32_NetworkAdapter.ConfigManagerErrorCode))
    	}
    	$objNIC | Add-Member -type scriptproperty -Name "NetConnectionStatus" -Value `
    	{
    	[hashtable]$MAP_NetConnectionStatus = @{
    	0 = "Disconnected";
    	1 = "Connecting";
    	2 = "Connected";
    	3 = "Disconnecting";
    	4 = "Hardware not present";
    	5 = "Hardware disabled";
    	6 = "Hardware malfunction";
    	7 = "Media disconnected";
    	8 = "Authenticating";
    	9 = "Authentication succeeded";
    	10 = "Authentication failed";
    	11 = "Invalid address";
    	12 = "Credentials required";
    	}
    	$MAP_NetConnectionStatus.([int]$($this.Win32_NetworkAdapter.netconnectionstatus))
    	}
    	$colNICInfo += $objNIC
    	}
    	$colNICInfo
    }

    Wednesday, June 27, 2012 9:10 PM
  • Question - Why would you wrap every piece of the object in what appears to be the exact same property or method.  This is completely unnecesary.  The OP asked for two items.   YOU have created an even harder bit for the answer.

    It appears that you have taken some old VBScript and linearly converted it which has caused you to miss how POwerSHel actually works.

    This is what is needed.

    Get-WmiObject Win32_NetworkAdapter -filter 'IPEnabled="True"' -ComputerName $computerlist |
    select __SERVER, DNSServerSearchOrder

    This will return a collection of all servers in $serverlist and the DNS servers. 

    We can retuen as much of teh objkect as needed but there is seldom a need to recreate the whole object.  The object can be reformatted after the extraction if needed for a report.  In PowerShell we should always leave the data raw until it is all gathered and only modify the date  for use at the very end.


     


    ¯\_(ツ)_/¯


    • Edited by jrv Thursday, June 28, 2012 12:06 AM
    Thursday, June 28, 2012 12:03 AM
  • Answer - The function was written for other people to use

    I created scriptproperty shortcuts to the returned WMI object properties in order to make the return object easier to work with for other individuals. The function was used by coworkers who did not understand WMI objects, and these shortcuts made it easier to work with as they didn't need to know how to navigate the returned WMI object (ex: if a value was stored in the returned win32_NetworkAdapter vs. win32_NetworkAdapterConfiguration WMI object). Additionally, I was able to use hash tables to translate obscure integer values to usable text summaries for reporting purposes.

    I believe you intended for your code to reference Win32_NetworkAdapterConfiguration instead of Win32_NetworkAdapter.

    Keep in mind, you can have multiple instances of a Network Adapter config returned in win32_NetworkAdapterConfiguration per device (this will not happen on all systems). You need the associators of query in order to link the hardware device with the active config. I understand the poster is not interested in the hardware config, but unless you marry the config to a hardware device, you can unintentionally return information about inactive configs (as in your code).

    As to the recreation of the whole object, I was far less worried about system memory consumption vs. usability. I kept the raw WMI data accessible in the return object via the Win32_NetworkAdapter and Win32_NetworkAdapterConfiguration properties if needed.

    In summary, the script isn't something rehashed from vbscript and I didn't miss how powershell works - I just:

    1.) Understood a few nuances of the win32_NetworkAdapater / win32_NetworkAdapaterConfiguration WMI classes

    2.) Valued usability over memory efficiency as it was not a very limited resource in my case.

    3.) Valued modularity / code re-use a little more given the business scenario my function was written to satisfy.

    It's always a balance - and every individual has their own preference and each business situation can tip the scale one way or the other. I have seen your work in the forums before and admire your dedication to contributing the forum as well of the quality of your posts. Please do not take this as a negative response to your question. Happy Scripting!

    Thursday, June 28, 2012 5:00 PM
  • The OP asked for two items an not all of that.  The report is for the DNS servers by system.

    YOu are corerct.  I had a bad copy and los tthe configuration bit because I was cut and paeting from more than one script.

    Here is what it should have been.

    Get-WmiObject Win32_NetworkAdapterconfiguration -filter 'IPEnabled="True"' -ComputerName $computerlist |
    select __SERVER, DNSServerSearchOrder

    This will crate a complete report of all servers in the list and output it in a form that can be easily worked with.

    There is seldom a need to rename everything in WMI.  If you need to rename something then use a select like the foillwoing examples. This is the POweerSHel lway to mange objects.  Ter is no regenteration but we do rename some things in the reporting and extraction process.

    Using New-Object with a property hash also simplidies the output. We try top sdstay away from the old VBSxcrip conversions where some wnat to make PowerSHell work and look like VBScript.  This is counterproductive and leads to many very hard to find errors.  

    #method 1
    Get-WmiObject Win32_NetworkAdapterconfiguration -filter 'IPEnabled="True"' -ComputerName $computerlist |
    select @{N='ServerName';E={$_.__SERVER}},
           @{N='DNSServers';E={$dns='';foreach($s in $_.DNSServerSearchOrder){$dns+="$s`n"};$dns}}
    #method 2 - report generator
    Get-WmiObject Win32_NetworkAdapterconfiguration -filter 'IPEnabled="True"' -ComputerName $computerlist |
         ForEach-Object{
             $server=$_.__SERVER
             $_.DNSServerSearchOrder |
                ForEach-Object{         
                       New-Object PSObject -Property @{Server=$server;DNS=$_}
                }
             } | Format-Table -groupby server -property dns

    I recommend reading some of the PowerShell team blogs on how to approach PowerSHell to get the output you need with the least effort.  The Scripting Guy blog also has many excellent examples if you don't go back to far.  The early blog from PowerShell 1.0 also made the mistake of copy vsbcript coding.  This has since been addressed and you will not see it anymore.

    PowerShell should not require more effort than VBScrip.  It is an object system that supports declaritive coding.  Once you see how that works you will wonder why you took the long way around.

    Try the examples.  You will see that PowerShell is very easy to modify to get different outcomes as long as you leave the objects in as close to a raw form as possible until you need to generate output.

    The PoshTeam blog has a good article somewhere on how to do your scripts in stages.  Data gathering, filering and sorting, then output formatting.    That formula works for about 90% of all tasks.  If you review the design of teh CmdLets you will begin to see that they do an  almost perfect job of moedling this "staging" or "pipelining" of teh work.  In PosH 3.0 with WorkFlow this will become an alomst absolute requirement.  WOrkflows demand a staged approach and prefer tht objects are pssed as they are.  We can add to teh objects or update them but we should keep the full raw object in hand until we are ready for the output or finalization stage.


    ¯\_(ツ)_/¯

    Thursday, June 28, 2012 5:37 PM
  • I have used those methods frequently in the past. I chose to construct a scriptproperty based object as it would point to the raw data and help my coworkers to better understand the associated WMI Classes I was referencing in a readable manner. I also was toying around with the fact that a scriptproperty is executed each time you reference the property for fun at the time (apparently I need to get out more).

    The scripting guy blog is an excellent resource, I also highly recommend books written by Don Jones / Jeffery Hicks. Powershell 2.0 TFM is one of my favorites.

    Additionally, I think Don Jones' "Vbscript, WMI and ADSI" book is a great reference for WMI that many powershell users could benefit from.

    Looking forward to alot of the features of Powershell 3.0 :) - the MS team has really done a great job with Powershell.



    • Edited by Scriptabit Thursday, June 28, 2012 6:57 PM
    Thursday, June 28, 2012 6:55 PM
  • Yes - I read those a long time ago as a reviewer.  Don And Jeff used to make VBScript out of PowerShell.  You will notice they don't do that anymore.

    You could have easily extended the base object with just a couple of lines.  There is no need to copy everything.

    TO get the configuration just do this:
    $adapter.GetRelated('Win32_NetworkAdapterConfiguration')

    This will get the associated class.  You are suing the old VBScript method and it takes up a lot of typing.  The objects are exposed by PowerShell.  Use PowerShell.

    To extend an object just add to it like this no need to copy it.

    Here is the example including support from PowerShell.

    I use no manufactured objects and retain all of the settings of the adapter and its configuration. 

    Function Get-NICInfo{
        [CmdLetBinding()]
        Param(
            $computerlist=$env:computername
        )
        
        Begin{
            Write-Verbose "([datetime]::Now)Iniialiszing decode arrays"
        	$MAP_TCPIPNetbiosOptions = @(
        	    'EnableNetbiosViaDhcp',
        	    'EnableNetbios',
        	    'DisableNetbios'
        	)
        }
        process{
            $adapters = get-wmiobject Win32_NetworkAdapter -filter 'NetConnectionStatus IS NOT NULL' -ComputerName $computerlist
            $adapters | %{
                Write-Verbose "$([datetime]::Now) Processing: $($_.Name)"
            	$_|Add-Member -MemberType NoteProperty -Name Configuration -Value $($_.GetRelated('Win32_NetworkAdapterConfiguration')| select *)
            	$_|Add-Member -MemberType NoteProperty -Name NBOptions -Value $MAP_TCPIPNetbiosOptions[($_.Configuration.TCPIPNetbiosOptions)]
            	$_
                Write-Verbose "([datetime]::Now) Finished Processing: $($_.Name)"
            }
        }
        End{
                Write-Verbose "([datetime]::Now) ALl processing complete"
        }
    }
    Get-NICInfo -v

    This is the PowerShell way of gathering info and not the VBScript method. Once you learn PowerShell you will want to throw out those old VBScript ideas and approach things from a whole new angle.

    Look at teh few lines of code and how I now have every property of both objects included.  I also demoed how to decode a numeric or flag field using an array.  As you discovered all scritp properties execute every time referenced.  This can cause unwanted behaviors.

    If we want to set the output format for a numeric field we can do that in the PowerShell custom format file which will allow you to create default presentations just like Get-Process.  Note how Get-Process displays a formatted table even though none of the properties are formatted.

    The best place to format output is external to the command that gathers the data.  This allows us to divide up the tasks for better execution, understandability and code reuse.

    VBScript and linear coding modularity does not translate into OOP systems well.  It tends to need to undo what the OOP system has done as you have seen with this.  Think of it like compressing a compressed file.  Further compression may only make the file bigger.

    OOP systems are usually clean and very easy to work with in there default form.  Retrofitting a car with a high tech engine that runs on flubber with a steam engine because you do not understand how flubber works is going backwards.  It may be more understandable but it is a step backwards.  What if Einstein had done that instead of pressing on even when he disagreed with his own findings,

    Try the above approach a couple of times and you will see what I mean.  (less typing too)

     


    ¯\_(ツ)_/¯

    Thursday, June 28, 2012 8:12 PM