Shared posts

01 Apr 14:38

Burning a match - does it get rid of nasty bathroom odors?

Two chemists attempt to answer this age-old question.
09 Jan 19:46

CodeSOD: Good Idea, Bad Idea

by Remy Porter
Stein Bjørndal

This will bring the wrath of the coding gods!

After years of neglecting their command line tools, Microsoft decided to try and build a grown-up set of administrative tools, and released PowerShell. Nearly a decade later, and many of their flagship services still don’t integrate neatly with PowerShell. Good Idea, Bad Idea The syntax is a bit messy, and the promises of an object-oriented shell never quite came to fruition. PowerShell is a great idea, executed poorly. For all that, it still offers certain advantages compared to the Unix family of shells, and is certainly worlds better than ol’ CMD.EXE.

Speaking of good ideas executed poorly: backups aren’t a good idea, they’re a great idea. And when Tommy took over as an Active Directory engineer, he was happy to hear that his predecessor had left behind a script that backed up all their user data on a daily basis. Tommy was significantly less happy when he saw the script.

Import-Module ActiveDirectory
$Date1 = get-date -uformat "%m-%d-%Y"
$LogFile = "D:\Reports\UserInfoDetailed.$Date1.csv"
echo "AccountExpirationDate*accountExpires*AccountLockoutTime*AccountNotDelegated*AllowReversiblePasswordEncryption*BadLogonCount*badPasswordTime*badPwdCount*C*CannotChangePassword*CanonicalName*City*CN*codePage*Comment*Company*Country*countryCode*Created*createTimeStamp*Deleted*Department*Description*DisplayName*DistinguishedName*Division*DoesNotRequirePreAuth*dSCorePropagationData*EmailAddress*EmployeeID*EmployeeNumber*employeeType*Enabled*$extensionAttribute10*$extensionAttribute13*Fax*GivenName*HomeDirectory*HomedirRequired*HomeDrive*HomePage*HomePhone*Initials*instanceType*isCriticalSystemObject*isDeleted*LastBadPasswordAttempt*LastKnownParent*LastLogonDate*LockedOut*lockoutTime*LogonWorkstations*Manager*MemberOf*MNSLogonAccount*MobilePhone*Modified*modifyTimeStamp*Name*nTSecurityDescriptor*ObjectCategory*ObjectClass*ObjectGUID*objectSid*Office*OfficePhone*Organization*OtherName*PasswordExpired*PasswordLastSet*PasswordNeverExpires*PasswordNotRequired*POBox*PostalCode*PrimaryGroup*primaryGroupID*ProfilePath*ProtectedFromAccidentalDeletion*pwdLastSet*SamAccountName*sAMAccountType*ScriptPath*sDRightsEffective*ServicePrincipalNames*SID*SIDHistory*SmartcardLogonRequired*State*StreetAddress*Surname*Title*TrustedForDelegation*TrustedToAuthForDelegation*UseDESKeyOnly*userAccountControl*UserPrincipalName*uSNChanged*uSNCreated*whenChanged*whenCreated" > $Logfile
# get-adUser -filter * -Property * | select * -Exclude userCertificate, showInAddressBook, Certificates | Export-csv $LogFile -NoTypeInformation
get-adUser -filter * -Property SamAccountName | Select SamAccountName | Foreach {$_.SamAccountName} > Accounts.txt
        $Accounts = get-content Accounts.txt
        Foreach ($Account in $Accounts)
                {$AccountExpirationDate = get-adUser $Account -Properties AccountExpirationDate | select AccountExpirationDate | Foreach {$_.AccountExpirationDate}
                $accountExpires = get-adUser $Account -Properties accountExpires | select accountExpires | Foreach {$_.accountExpires}
                $AccountLockoutTime = get-adUser $Account -Properties AccountLockoutTime | select AccountLockoutTime | Foreach {$_.AccountLockoutTime}
                $AccountNotDelegated = get-adUser $Account -Properties AccountNotDelegated | select AccountNotDelegated | Foreach {$_.AccountNotDelegated}
                $AllowReversiblePasswordEncryption = get-adUser $Account -Properties AllowReversiblePasswordEncryption | select AllowReversiblePasswordEncryption | Foreach {$_.AllowReversiblePasswordEncryption}
                $BadLogonCount = get-adUser $Account -Properties BadLogonCount | select BadLogonCount | Foreach {$_.BadLogonCount}
                $badPasswordTime = get-adUser $Account -Properties badPasswordTime | select badPasswordTime | Foreach {$_.badPasswordTime}
                $badPwdCount = get-adUser $Account -Properties badPwdCount | select badPwdCount | Foreach {$_.badPwdCount}
                $C = get-adUser $Account -Properties C | select C | Foreach {$_.C}
                $CannotChangePassword = get-adUser $Account -Properties CannotChangePassword | select CannotChangePassword | Foreach {$_.CannotChangePassword}
                $CanonicalName = get-adUser $Account -Properties CanonicalName | select CanonicalName | Foreach {$_.CanonicalName}
                $City = get-adUser $Account -Properties City | select City | Foreach {$_.City}
                $CN = get-adUser $Account -Properties CN | select CN | Foreach {$_.CN}
                $codePage = get-adUser $Account -Properties codePage | select codePage | Foreach {$_.codePage}
                $comment = Get-ADUser $Account -Properties * | select -ExpandProperty commentForeach {$_.comment}
                $Company = get-adUser $Account -Properties Company | select Company | Foreach {$_.Company}
                $Country = get-adUser $Account -Properties Country | select Country | Foreach {$_.Country}
                $countryCode = get-adUser $Account -Properties countryCode | select countryCode | Foreach {$_.countryCode}
                $Created = get-adUser $Account -Properties Created | select Created | Foreach {$_.Created}
                $createTimeStamp = get-adUser $Account -Properties createTimeStamp | select createTimeStamp | Foreach {$_.createTimeStamp}
                $Deleted = get-adUser $Account -Properties Deleted | select Deleted | Foreach {$_.Deleted}
                $Department = get-adUser $Account -Properties Department | select Department | Foreach {$_.Department}
                $Description = get-adUser $Account -Properties Description | select Description | Foreach {$_.Description}
                $DisplayName = get-adUser $Account -Properties DisplayName | select DisplayName | Foreach {$_.DisplayName}
                $DistinguishedName = get-adUser $Account -Properties DistinguishedName | select DistinguishedName | Foreach {$_.DistinguishedName}
                $Division = get-adUser $Account -Properties Division | select Division | Foreach {$_.Division}
                $DoesNotRequirePreAuth = get-adUser $Account -Properties DoesNotRequirePreAuth | select DoesNotRequirePreAuth | Foreach {$_.DoesNotRequirePreAuth}
                $dSCorePropagationData = get-adUser $Account -Properties dSCorePropagationData | select -ExpandProperty dSCorePropagationData
                $EmailAddress = get-adUser $Account -Properties EmailAddress | select EmailAddress | Foreach {$_.EmailAddress}
                $EmployeeID = get-adUser $Account -Properties EmployeeID | select EmployeeID | Foreach {$_.EmployeeID}
                $EmployeeNumber = get-adUser $Account -Properties EmployeeNumber | select EmployeeNumber | Foreach {$_.EmployeeNumber}
                $employeeType = get-adUser $Account -Properties employeeType | select employeeType | Foreach {$_.employeeType}
                $Enabled = get-adUser $Account -Properties Enabled | select Enabled | Foreach {$_.Enabled}
                $extensionAttribute10 = get-adUser $Account -Properties extensionAttribute10 | select extensionAttribute10 | Foreach {$_.extensionAttribute10}
                $extensionAttribute13 = get-adUser $Account -Properties extensionAttribute13 | select extensionAttribute13 | Foreach {$_.extensionAttribute13}
                $Fax = get-adUser $Account -Properties Fax | select Fax | Foreach {$_.Fax}
                $GivenName = get-adUser $Account -Properties GivenName | select GivenName | Foreach {$_.GivenName}
                $HomeDirectory = get-adUser $Account -Properties HomeDirectory | select HomeDirectory | Foreach {$_.HomeDirectory}
                $HomedirRequired = get-adUser $Account -Properties HomedirRequired | select HomedirRequired | Foreach {$_.HomedirRequired}
                $HomeDrive = get-adUser $Account -Properties HomeDrive | select HomeDrive | Foreach {$_.HomeDrive}
                $HomePage = get-adUser $Account -Properties HomePage | select HomePage | Foreach {$_.HomePage}
                $HomePhone = get-adUser $Account -Properties HomePhone | select HomePhone | Foreach {$_.HomePhone}
                $Initials = get-adUser $Account -Properties Initials | select Initials | Foreach {$_.Initials}
                $instanceType = get-adUser $Account -Properties instanceType | select instanceType | Foreach {$_.instanceType}
                $isCriticalSystemObject = get-adUser $Account -Properties isCriticalSystemObject | select isCriticalSystemObject | Foreach {$_.isCriticalSystemObject}
                $isDeleted = get-adUser $Account -Properties isDeleted | select isDeleted | Foreach {$_.isDeleted}
                $LastBadPasswordAttempt = get-adUser $Account -Properties LastBadPasswordAttempt | select LastBadPasswordAttempt | Foreach {$_.LastBadPasswordAttempt}
                $LastKnownParent = get-adUser $Account -Properties LastKnownParent | select LastKnownParent | Foreach {$_.LastKnownParent}
                $LastLogonDate = get-adUser $Account -Properties LastLogonDate | select LastLogonDate | Foreach {$_.LastLogonDate}
                $LockedOut = get-adUser $Account -Properties LockedOut | select LockedOut | Foreach {$_.LockedOut}
                $lockoutTime = get-adUser $Account -Properties lockoutTime | select lockoutTime | Foreach {$_.lockoutTime}
                $LogonWorkstations = get-adUser $Account -Properties LogonWorkstations | select LogonWorkstations | Foreach {$_.LogonWorkstations}
                $Manager = get-adUser $Account -Properties Manager | select Manager | Foreach {$_.Manager}
                $MemberOf = get-adUser $Account -Properties MemberOf | select -ExpandProperty MemberOf
                $MNSLogonAccount = get-adUser $Account -Properties MNSLogonAccount | select MNSLogonAccount | Foreach {$_.MNSLogonAccount}
                $MobilePhone = get-adUser $Account -Properties MobilePhone | select MobilePhone | Foreach {$_.MobilePhone}
                $Modified = get-adUser $Account -Properties Modified | select Modified | Foreach {$_.Modified}
                $modifyTimeStamp = get-adUser $Account -Properties modifyTimeStamp | select modifyTimeStamp | Foreach {$_.modifyTimeStamp}
                #$msDS-User-Account-Control-Computed = get-adUser $Account -Properties msDS-User-Account-Control-Computed | select msDS-User-Account-Control-Computed | Foreach {$_.msDS-User-Account-Control-Computed}
                $Name = get-adUser $Account -Properties Name | select Name | Foreach {$_.Name}
                $nTSecurityDescriptor = get-adUser $Account -Properties nTSecurityDescriptor | select nTSecurityDescriptor | Foreach {$_.nTSecurityDescriptor}
                $ObjectCategory = get-adUser $Account -Properties ObjectCategory | select ObjectCategory | Foreach {$_.ObjectCategory}
                $ObjectClass = get-adUser $Account -Properties ObjectClass | select ObjectClass | Foreach {$_.ObjectClass}
                $ObjectGUID = get-adUser $Account -Properties ObjectGUID | select ObjectGUID | Foreach {$_.ObjectGUID}
                $objectSid = get-adUser $Account -Properties objectSid | select objectSid | Foreach {$_.objectSid}
                $Office = get-adUser $Account -Properties Office | select Office | Foreach {$_.Office}
                $OfficePhone = get-adUser $Account -Properties OfficePhone | select OfficePhone | Foreach {$_.OfficePhone}
                $Organization = get-adUser $Account -Properties Organization | select Organization | Foreach {$_.Organization}
                $OtherName = get-adUser $Account -Properties OtherName | select OtherName | Foreach {$_.OtherName}
                $PasswordExpired = get-adUser $Account -Properties PasswordExpired | select PasswordExpired | Foreach {$_.PasswordExpired}
                $PasswordLastSet = get-adUser $Account -Properties PasswordLastSet | select PasswordLastSet | Foreach {$_.PasswordLastSet}
                $PasswordNeverExpires = get-adUser $Account -Properties PasswordNeverExpires | select PasswordNeverExpires | Foreach {$_.PasswordNeverExpires}
                $PasswordNotRequired = get-adUser $Account -Properties PasswordNotRequired | select PasswordNotRequired | Foreach {$_.PasswordNotRequired}
                $POBox = get-adUser $Account -Properties POBox | select POBox | Foreach {$_.POBox}
                $PostalCode = get-adUser $Account -Properties PostalCode | select PostalCode | Foreach {$_.PostalCode}
                $PrimaryGroup = get-adUser $Account -Properties PrimaryGroup | select PrimaryGroup | Foreach {$_.PrimaryGroup}
                $primaryGroupID = get-adUser $Account -Properties primaryGroupID | select primaryGroupID | Foreach {$_.primaryGroupID}
                $ProfilePath = get-adUser $Account -Properties ProfilePath | select ProfilePath | Foreach {$_.ProfilePath}
                $ProtectedFromAccidentalDeletion = get-adUser $Account -Properties ProtectedFromAccidentalDeletion | select ProtectedFromAccidentalDeletion | Foreach {$_.ProtectedFromAccidentalDeletion}
                $pwdLastSet = get-adUser $Account -Properties pwdLastSet | select pwdLastSet | Foreach {$_.pwdLastSet}
                $SamAccountName = get-adUser $Account -Properties SamAccountName | select SamAccountName | Foreach {$_.SamAccountName}
                $sAMAccountType = get-adUser $Account -Properties sAMAccountType | select sAMAccountType | Foreach {$_.sAMAccountType}
                $ScriptPath = get-adUser $Account -Properties ScriptPath | select ScriptPath | Foreach {$_.ScriptPath}
                $sDRightsEffective = get-adUser $Account -Properties sDRightsEffective | select sDRightsEffective | Foreach {$_.sDRightsEffective}
                $ServicePrincipalNames = get-adUser $Account -Properties ServicePrincipalNames | select -ExpandProperty ServicePrincipalNames
                $SID = get-adUser $Account -Properties SID | select SID | Foreach {$_.SID}
                $SIDHistory = get-adUser $Account -Properties SIDHistory | select -ExpandProperty SIDHistory
                $SmartcardLogonRequired = get-adUser $Account -Properties SmartcardLogonRequired | select SmartcardLogonRequired | Foreach {$_.SmartcardLogonRequired}
                $State = get-adUser $Account -Properties State | select State | Foreach {$_.State}
                $StreetAddress = get-adUser $Account -Properties StreetAddress | select StreetAddress | Foreach {$_.StreetAddress}
                $Surname = get-adUser $Account -Properties Surname | select Surname | Foreach {$_.Surname}
                $Title = get-adUser $Account -Properties Title | select Title | Foreach {$_.Title}
                $TrustedForDelegation = get-adUser $Account -Properties TrustedForDelegation | select TrustedForDelegation | Foreach {$_.TrustedForDelegation}
                $TrustedToAuthForDelegation = get-adUser $Account -Properties TrustedToAuthForDelegation | select TrustedToAuthForDelegation | Foreach {$_.TrustedToAuthForDelegation}
                $UseDESKeyOnly = get-adUser $Account -Properties UseDESKeyOnly | select UseDESKeyOnly | Foreach {$_.UseDESKeyOnly}
                $userAccountControl = get-adUser $Account -Properties userAccountControl | select userAccountControl | Foreach {$_.userAccountControl}
                $UserPrincipalName = get-adUser $Account -Properties UserPrincipalName | select UserPrincipalName | Foreach {$_.UserPrincipalName}
                $uSNChanged = get-adUser $Account -Properties uSNChanged | select uSNChanged | Foreach {$_.uSNChanged}
                $uSNCreated = get-adUser $Account -Properties uSNCreated | select uSNCreated | Foreach {$_.uSNCreated}
                $whenChanged = get-adUser $Account -Properties whenChanged | select whenChanged | Foreach {$_.whenChanged}
                $whenCreated = get-adUser $Account -Properties whenCreated | select whenCreated | Foreach {$_.whenCreated}
                #$PropertyNames = get-adUser $Account -Properties PropertyNames | select PropertyNames | Foreach {$_.PropertyNames}
                #$PropertyCount = get-adUser $Account -Properties PropertyCount | select PropertyCount | Foreach {$_.PropertyCount}
                echo "$AccountExpirationDate*$accountExpires*$AccountLockoutTime*$AccountNotDelegated*$AllowReversiblePasswordEncryption*$BadLogonCount*$badPasswordTime*$badPwdCount*$C*$CannotChangePassword*$CanonicalName*$City*$CN*$codePage*$comment*$Company*$Country*$countryCode*$Created*$createTimeStamp*$Deleted*$Department*$Description*$DisplayName*$DistinguishedName*$Division*$DoesNotRequirePreAuth*$dSCorePropagationData*$EmailAddress*$EmployeeID*$EmployeeNumber*$employeeType*$Enabled*$extensionAttribute10*$extensionAttribute13*$Fax*$GivenName*$HomeDirectory*$HomedirRequired*$HomeDrive*$HomePage*$HomePhone*$Initials*$instanceType*$isCriticalSystemObject*$isDeleted*$LastBadPasswordAttempt*$LastKnownParent*$LastLogonDate*$LockedOut*$lockoutTime*$LogonWorkstations*$Manager*$MemberOf*$MNSLogonAccount*$MobilePhone*$Modified*$modifyTimeStamp*$Name*$nTSecurityDescriptor*$ObjectCategory*$ObjectClass*$ObjectGUID*$objectSid*$Office*$OfficePhone*$Organization*$OtherName*$PasswordExpired*$PasswordLastSet*$PasswordNeverExpires*$PasswordNotRequired*$POBox*$PostalCode*$PrimaryGroup*$primaryGroupID*$ProfilePath*$ProtectedFromAccidentalDeletion*$pwdLastSet*$SamAccountName*$sAMAccountType*$ScriptPath*$sDRightsEffective*$ServicePrincipalNames*$SID*$SIDHistory*$SmartcardLogonRequired*$State*$StreetAddress*$Surname*$Title*$TrustedForDelegation*$TrustedToAuthForDelegation*$UseDESKeyOnly*$userAccountControl*$UserPrincipalName*$uSNChanged*$uSNCreated*$whenChanged*$whenCreated" >> $Logfile
                #echo "$AccountExpirationDate*$accountExpires*$AccountLockoutTime*$AccountNotDelegated*$AllowReversiblePasswordEncryption*$BadLogonCount*$badPasswordTime*$badPwdCount*$CannotChangePassword*$CanonicalName*$City*$CN*$codePage*$Company*$Country*$countryCode*$Created*$createTimeStamp*$Deleted*$Department*$Description*$DisplayName*$DistinguishedName*$Division*$DoesNotRequirePreAuth*$dSCorePropagationData*$EmailAddress*$EmployeeID*$EmployeeNumber*$employeeType*$Enabled*$Fax*$GivenName*$HomeDirectory*$HomedirRequired*$HomeDrive*$HomePage*$HomePhone*$Initials*$instanceType*$isCriticalSystemObject*$isDeleted*$LastBadPasswordAttempt*$LastKnownParent*$LastLogonDate*$LockedOut*$lockoutTime*$LogonWorkstations*$Manager*$MemberOf*$MNSLogonAccount*$MobilePhone*$Modified*$modifyTimeStamp*$Name*$nTSecurityDescriptor*$ObjectCategory*$ObjectClass*$ObjectGUID*$objectSid*$Office*$OfficePhone*$Organization*$OtherName*$PasswordExpired*$PasswordLastSet*$PasswordNeverExpires*$PasswordNotRequired*$POBox*$PostalCode*$PrimaryGroup*$primaryGroupID*$ProfilePath*$ProtectedFromAccidentalDeletion*$pwdLastSet*$SamAccountName*$sAMAccountType*$ScriptPath*$sDRightsEffective*$ServicePrincipalNames*$SID*$SIDHistory*$SmartcardLogonRequired*$State*$StreetAddress*$Surname*$Title*$TrustedForDelegation*$TrustedToAuthForDelegation*$UseDESKeyOnly*$userAccountControl*$UserPrincipalName*$uSNChanged*$uSNCreated*$whenChanged*$whenCreated" >> $Logfile
        }
[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll 👍 today.Your first 30 days are free on us. Learn more at Scout.
01 Sep 07:26

The Old Ways

by Erik Gern

Greg never thought he’d meet a real-life mentat.

“We’re so happy to have you aboard,” said Jordan, the CEO of IniTech. She showed Greg to the back end of the office, to a closed door marked with just one word: Frank. Jordan, not bothering to knock, opening the door.

A mentat from the film Dune

Greg was overwhelmed with the stench of burned coffee and old-man smell. The office was unadorned and dark, the blinds drawn, illuminated by the blue light coming from an aging CRT screen. He saw a wrinkled scalp behind a tall, black office chair.

“I’m busy,” Frank said.

Jordan cleared her throat. “This is your new programming partner.”

“I’m Greg. It’s nice to meet you–” Greg offered his hand, but a wrinkled appendage slapped it away.

“Get yourself a chair. I know where everything is. You just show me you can type.”

Greg shot Jordan a glance as they left Frank’s office.

“He’s been with us 22 years,” she said. “He knows everything about our code. But his typing’s not what it used to be. Just do what he says. With some luck he’ll be retiring in a few months.”

Total Recall

Greg pulled a spare office chair into Frank’s den. He could see Frank’s face in profile now, resembling the mummy of Rameses II. Frank slid his keyboard to Greg. “Open C:\project.make in Vim,” Frank said, “and go to line 22.”

Greg thought it was odd that a makefile would right under C:\, but he did so. He moved the cursor to line 22.

“Increment $VERSION to 8.3.3.”

Greg noticed that Frank had his eyes shut, but humored him. In fact, line 22 did declare a $VERSION constant, and Greg changed it to 8.3.3.

“You’ll be suitable,” Frank said, crossing his arms. “You’ll do your work from the SMB server. Don’t make any changes without my authorization first.”

Change Management

Back at his desk, Greg found the SMB server where Frank kept all of his code. Or rather, the SMB mapped all of the files on Frank’s hard drive. Curious, Greg searched for .pas, .make, and other source files, wondering why Frank would keep his principle makefile under C:\.

There were 440 source files, about 200 megabytes, spread out all over the directory strucure. C:\Windows\System32, C:\Users\Shared\Project, C:\Program Files\… Frank’s entire computer was the de facto source repository.

Greg knew if he ever had to make an on-the-fly change to the source, it would take hours just tracking down the right file on SMB. Surely they had a repository he could check changes into. Greg took a deep breath and re-entered Frank’s den.

“Frank, do we have any of this in a repo somewhere? I don’t want to SMB onto your computer every time we make a change. What if we have to patch something overnight?”

“What?!” Frank rose from his office chair, unsteady on his disused legs. “There will be no code changes without my direct supervision! It’s worked just fine for 22 years. Is that understood?”

In Memory

Greg endured this for several months. Frank would harbor no suggestions of version control or repos. Everything, Frank said, was in his head. As long as no one changed the source without his permission, he would know where everything was.

Despite his frustrations, it greatly impressed Greg. Especially when Frank had memorized loop variables such as these:

for RecursiveWaypointCompressionThreadModuleIndexVerifierPropertyHandleIndex := 1 to 99 do ...  

Less amusing was Frank’s insistence on using HEX constants for any encoded string. “You can’t trust any string encoding,” Frank said. It even extended to embedded web pages in their embedded manual:

const
    ThirdWebPage : array of byte = [ $2d, $20, ... 660k OF HEX CONSTS..... ];
    JQuery33WebPage : array of byte = [ $2d, $20, ... 3,660k OF HEX CONSTS..... ];  

But Greg wondered. What would happen if he slipped in just a little change? How long would it take before Frank found out?

One night, he came into the office and logged into Frank’s SMB server. He opened a file and found an innocuous for-loop block. He replaced the twenty-something variable name with i, saved a backup on his own machine, and went home.

Greg arrived in the office late that morning, stuck in traffic, and was met by Jordan at the door. “Keep this quiet, but Frank just passed away.”

“Was it last night?”

“Brain aneurysm in his sleep.”

Frank probably died before he had a chance to see Greg’s unauthorized change. Greg would never know if Frank actually had the entire codebase memorized. Sometimes Greg would memorize a line or two, or find himself looking up mnemonic tricks to remember long sequences of characters. But it wasn’t like Frank rubbed off on him. Not really.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
04 Nov 12:50

Watermelon Caprese Salad with Lemon Zest

by meatified

Mr Meatified discovered fairly recently that he loves traditional Caprese Salad (after years of claiming he couldn’t stand the stuff, naturally!). Since it’s been so hot, I’ve made him quite a few this summer. To make it more of a...

The post Watermelon Caprese Salad with Lemon Zest appeared first on meatified.