user2219572
user2219572

Reputation: 61

Get system installation date programmatically

I am trying to get the system installation date by running a console app. The only way I know how to do this is by parsing the /var/log/install.log file for the latest string containing OSInstaller & Install Complete items.

Is there a handy system API I am missing?

Upvotes: 1

Views: 1558

Answers (3)

byrdhound
byrdhound

Reputation: 11

system_profiler SPInstallHistoryDataType | grep macOS -A 4

This command will return the full list of all installations (initial one and all the OS updates with their corresponding installation date. As /System/Library/Receipts is an empty directory in current versions of macOS, this one seems to be the best way to retrieve the installation date. Next step would then be to parse the output to get a condensed list with OS version and installation date.

Upvotes: 1

user2219572
user2219572

Reputation: 61

So in case, someone finds this useful.

Swift 3.0

SOLUTION 1

Initially I parsed /var/log/install.log file to get date string:

    // To get OS installation date we'll need to check system log file and find entry which contains installation date
var systemDates : String? = nil
do {
    let fullSystemLog = try NSString(contentsOf: URL(fileURLWithPath: "/var/log/install.log"), encoding: String.Encoding.utf8.rawValue)
    let entries = fullSystemLog.components(separatedBy: "\n")
    //Filter to get only entries about OS installation
    let filtered = entries.filter{ entry in
        return entry.contains("OSInstaller") && entry.contains("Install Complete") //Markers telling that OS was installed
    }

    var latestMention = ""
    if filtered.count > 0 {
        //If 1 or more entries found we'll pick last one
        latestMention = filtered.last!
    }
    else if entries.count > 0 {
        //If there are 0 mentions of OS installation - we'll use first entry in logs
        latestMention = entries.first!
    }

    //parse picked entry for date
    do {
        let regex = try NSRegularExpression(pattern: ".+:[0-9]{2}", options: [])
        let nsString = latestMention as NSString
        let results = regex.matches(in: latestMention,
                                    options: [], range: NSMakeRange(0, nsString.length))
        let actualDateSubstrings = results.map { nsString.substring(with: $0.range)}

        if let dateStringFromMention = actualDateSubstrings.first {

            systemDates = dateStringFromMention
        }
        else {
            systemDates = "<Error: no date results>"
        }

    } catch let error as NSError {
        systemDates = "<Error: invalid regex: \(error.localizedDescription)>"
    }
} 
catch {
    systemDates = "<Error: system log file not found>"
}

print("\tSYSTEM INSTALLED: \(systemDates)")

SOLUTION 2

The second solution appears much simpler. Look into the InstallDate field of /System/Library/Receipts/com.apple.pkg.BaseSystemResources.plist:

let systemDates = NSDictionary(contentsOfFile: "/System/Library/Receipts/com.apple.pkg.BaseSystemResources.plist")

print("\tSYSTEM INSTALLED: \(systemDates?["InstallDate"])")

Upvotes: -1

CRD
CRD

Reputation: 53000

As a suggestion for exploration only:

You could try looking at the files /System/Library/Receipts.

You will probably see a com.apple.pkg.BaseSystemResources.plist file, its modification date may tell you when the OS was installed.

There are also com.apple.pkg.update.os.*.plist files for updates, again look at the modification dates and maybe parse the wildcard (*) bit if you can determined a naming convention.

HTH, Happy Hunting!

Upvotes: 1

Related Questions