Technical Article

PoSh: Get-WhoInstallSQL

,

Anytime a new server comes into our support, it is useful to know who installed SQL, and if it was the customer, developer, or a member of your own team (or even yourself and just don't remember)

This is my very first powershell script. Just run it from the target server,

Load the function, and run it as

Get-WhoInstalledSQL

Caveat:

This script searches your setup bootstrap folder

So if prior admins deleted the content of those folders, the script will say "cannot find information"

Any questions, please let me know.

Found a typo? A problem? You think you can do better?

Please let me know! As I said, this is my first PoSh script and I really need the input to get better and better.

Thank you

Miguel Quintana

#cls
function Get-WhoInstalledSQL {

#[Cmdletbinding()]
       BEGIN
       {
        $r           = @()
        $UserName    = @()
        $InstanceName= @()
        $CreationTime= @()   
        }

       PROCESS {

# $rootfolder
$r = "C:\Program Files\Microsoft SQL Server"

# Finds all configurationfile.ini

$InstallFile = (Get-ChildItem -Recurse -path $r -include "configurationfile.ini" )

# Test for existence of INI file
if (!$InstallFile) {
  write-Output " The Setup Bootstrap folder does not have this info" 
}
# this ELSE essentially exits the function
ELSE {

$listconfig = @()

FOREACH ($configfile in $InstallFile)
{
# First filters in all "install" files
# Then filters all the ones that actuall install the engine
if (get-content $configFile | Select-String -pattern "ACTION=`"Install*")
    {if (get-content $configFile | Select-String -pattern "FEATURES=SQLENGINE")
        {
            $listconfig += $configfile
        }

    }

}

# Test that if we have INI file, it is for INSTALL actions
if (!$listconfig) {
  write-Output " The Setup Bootstrap folder does not have this info" 
}
# this ELSE essentially exits the function
ELSE {

# At this point, we have the configurationFile.ini 
# Get there are log files at this folder level who keep information of who the username used at the time of installation
# The log for the engine is sql_engine_core_inst_cpu??_1.log. 
# Where it can be 32 or 64 bits

# It will pass the FOR loop as many config files are found
# But the If will execute only for 

for ($i=0;$i -lt $listconfig.length;$i++)
    {

        $InstallPath = split-path $listconfig[$i] -parent
        $installLog = Get-ChildItem -Recurse -path $InstallPath -include "sql_engine_core_inst_Cpu??_1.log"  | sort LastWriteTime | select -First 1
        # Ok we got the file, do we have a match?
        # We do this check to make sure we have the right file
        
        
        if($installlog.FullName)
            {
            # Get the user who install it, from the log file
            $Line=Get-Content $installLog  | Select-String -pattern "C:\\Users\\" | Select-Object -First 1

            #
            $UserName += (($Line -split("C:\\Users\\")  | select-object -last 1).split("\\") | Select-Object -First 1)
            }
        elseif(!$installLog)
            { $UserName= "Not_Found" }    
            
        
        # SQL Instance Name from INI file
        $InstanceName +=(get-content $listconfig[$i] | Select-String -pattern "INSTANCEID=") -replace "INSTANCEID=","" -replace "`"",""
            
        # Get CreationTime attribute  from INI file
        $CreationTime += (Get-ChildItem $listconfig[$i] | select creationtime).creationtime
     }

$table=@()

for ($i=0;$i -lt $InstanceName.length;$i++)
{
$table +=[pscustomobject]@{
            "InstanceName"=$InstanceName[$i]
            "CreationTime"=$CreationTime[$i]
            "UserName"    =$UserName[$i] 
                            }
}

  Write-Output $table
  
    }  # closing the ELSE statement  
    }  # closing the ELSE statement
    # end process
    }
}


# Get-WhoInstalledSQL

Rate

5 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

5 (1)

You rated this post out of 5. Change rating