1000 Faces

1000 Faces

Need 1000 or unique user photos for your lab? There is a great website for just such a thing. https://thispersondoesnotexist.com/image. Let’s break down some code to see how we can pull a few hundred pictures.

The first thing we need to know is how many we want. We are going to get 1000 faces for this example. Next, we need a safe location. Finally, we need an sleep time for the site to regenerate an image. Lets get started.

$StartCount..$FinishCount

the two . in this code allows you to loop through two values. Next we need to pipe this command into a foreach object loop.

$StartCount..$FinishCount | foreach-object {}

Inside the for each loop we start the real work. We are going to use the Invoke-WebRequest. Our URI is the site “https://thispersondoesnotexist.com/image” We will select where we want to save the file using the -outfile location. We are going to save it in the save location we choose earlier. We will put the name as the number you are currently using. Finally we will add a -disablekeepalive flag to stop the system from keeping the connection alive. We do this out of respect for the site.

Invoke-WebRequest -Uri $URL -OutFile "$SaveFolder\$_.jpg" -DisableKeepAlive

Next we need to do a sleep cycle. We do this because if we do a request after another request, we will get the same image. 7 Seconds seems to be the magic number. We do this with Start-Sleep -Seconds 7.

Start-Sleep -Seconds 7

That’s it, It’s a simple process. The Invoke-WebRequest will get the needed image and save it to your computer. The site will generate a new picture each time you reach out.

The Scripts

Here is the script below.

function Get-Faces {
    param (
        [int]$StartCount = 1,
        [int]$FinishCount = 1000,
        [int]$SecondsToSleep = 7,
        [string]$SaveFolder = "C:\Dpb\100000 Faces"
    )
    $URL = 'https://thispersondoesnotexist.com/image'
    $StartCount..$FinishCount | foreach-object {
        Invoke-WebRequest -Uri $URL -OutFile "$SaveFolder\$_.jpg" -DisableKeepAlive
         Start-Sleep -Seconds $SecondsToSleep
    }
}

Have fun with this little guy, just remember to be respectful of the sites you are pulling information from.

Numlock On Startup

Numlock On Startup

I hate it when I start up my PC and my number lock is turned off. Did you know you can set this to be automatic. Yep that’s right, automatic. Start up powershell as administrator and run the single line of code below. Then you should be set to go.

Set-Itemproperty -Path 'HKU:\.DEFAULT\Control Panel\Keyboard\' -Name 'InitialKeyboardIndicators' -Value '2'

Use wisely fellow admins.

Tattooing with Group Policy

Tattooing with Group Policy

No, we are not using group policy to put your skull and crossbones tattoo on people. Tattooing is in reference to policies that make changes to the registry that are not removed after the policy is removed. These changes are Permanent and require the admin to manually remove them. I have seen Tattooing become a problem after windows upgrade/update. Polices that effect anything outside 4 registry zones, will tattoo.

  • HKEY_LOCAL_MACHINE\SOFTWARE\Policies
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies
  • HKEY_CURRENT_USER\SOFTWARE\Policies
  • HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies

Thankfully, most out-of-box Microsoft windows policies fall under these four registry keys. Microsoft has also made almost everything they need to be inside these registry keys as well. For example, all the explorer policies live under:

HKCU\Software\Micorosoft\Windows\CurrrentVersion\Policies\Explorer

Thus whenever you remove a policy setting for the Explorer, when the computer pulls down the new policy settings, it will detect the change and remove the explorer policies that were in place.

What kind of policies will tattoo then if everything is set to write to the correct registry locations? Well, custom software will do this. Back in the day, Adobe Reader’s ADM would write to HKLM\Softwares\Adobe. Thankfully it now writes to the policies hive. Chrome will also do this and sometimes needs to be manually removed.

Other Types of Tattooing

Anything that changes the system as a whole. For example, Folder Redirection policies can leave people’s folders on other servers and such. Roaming profiles also provide issues as the files live on another server. My favorite problem child is printers. The printer is installed and will need to be removed with the GPO or you will tattoo. Another good one is direct registry edits with group policy. Icons are another example of another tattooing. WDS application pushouts as well will tattoo the system with software.

Final Words

CYA! Always test a GPO before sending it out. Add it and then remove it. Research the GPO, and plan everything out. GPO is easy to do, almost a no brainer. Anyone can go to youtube and figure out how to do it. The truth behind GPO is why you should do it, and can it be undone. I have personally tattooed icons and printers in my past. So, always and I mean always, plan it out, test, undo, test again, and then deploy.

2FA and Outlook

2FA and Outlook

A friend’s company turned on 2fa for their office 365. When people logged into office.com they were prompted to 2-factor authenticate with the system. Some choose to call in, some choose text, and others choose the app. It was doing good, but outlook gave them troubles. It turns out that office 2013 and office 2016 installs struggle with 2fa. However, there is salvation! A registry edit.

for office 2013:

HKCU\SOFTWARE\Microsoft\Office\15.0\Common\Identity\EnableADAL

for Office 2016

HKCU\SOFTWARE\Microsoft\Office\16.0\Common\Identity\EnableADAL

Set this to a REG_DWORD of 1.

For more information, you can read all about it from the Microsoft documentation page:

https://docs.microsoft.com/en-us/microsoft-365/enterprise/modern-auth-for-office-2013-and-2016?view=o365-worldwide

Invoke-SHDMoveFiles

Invoke-SHDMoveFiles

Ever need a service that copies a single folder to multiple locations at once? This script will do just that. It will copy a single location to more than one location and even log the outcomes accordingly. Thus, you will be able to set this one up as a task and run it every so often.

Invoke-SHDMoveFiles {
    <#
    .SYNOPSIS
        Copy files from target source folders to a set of target folders.
    .DESCRIPTION
        Copys from multiple source folders to a select target folders. This allows archiving to occur.
        The folders are not auto created. Thus, the folders must exists. The script also adds a log file of any error
        messages you see. See notes for more details.
    .PARAMETER SourceFolder
        [String[]] SourceFolder is an Array of Strings of target folders to move the files from.
    .PARAMETER TargetFolder
        [String[]] TargetFolder is an Array of strings where the files will be copied to. This is not a one for one ratio. Thus all files will exist inside the targetfolder.
    .EXAMPLE
        ./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder\','C:\tbc\tmp\Source Folder 2\' -TargetFolder 'C:\tbc\tmp\Target Folder\','C:\tbc\tmp\Target Folder 2\'
        Moves all files from the source folder 1 and 2 to target folders 1 and 2.
    .EXAMPLE
        ./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder\' -TargetFolder 'C:\tbc\tmp\Target Folder\','C:\tbc\tmp\Target Folder 2\'
        Moves all files from the source folder 1 to target folders 1 and 2.
    .EXAMPLE
        ./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder 1\','C:\tbc\Tmp\Source Folder 2\','C:\tbc\Tmp\Source Folder 3\'  -TargetFolder 'C:\tbc\tmp\Target Folder\'
        Moves all files from the source folder 1, 2, and 3 to the target folder
    .EXAMPLE
        ./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder\','C:\tbc\tmp\Source Folder 2\' -TargetFolder 'C:\tbc\tmp\Target Folder\','C:\tbc\tmp\Target Folder 2\' -Recurse
        Moves all files under Source folder 1 and 2 to target folders 1 and 2.
    .EXAMPLE
        ./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder\' -TargetFolder 'C:\tbc\tmp\Target Folder\','C:\tbc\tmp\Target Folder 2\' -Recurse
        Moves all files under source folder 1 to target folders 1 and 2.
    .EXAMPLE
        ./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder 1\','C:\tbc\Tmp\Source Folder 2\','C:\tbc\Tmp\Source Folder 3\'  -TargetFolder 'C:\tbc\tmp\Target Folder\' -Recurse
        Moves all files under source folder 1, 2, and 3 to the target folder
    .INPUTS
        [String] Folder Paths
    .OUTPUTS
        No Output
    .NOTES
        Author: David Bolding
        Date: 8/16/2020
        Purpose: Moving files around and making archives
        Min Powershell Version: 4

        This command generates error logs located c:\tbc\SHDMoveFileLog.txt. The error logs structure is broken up in 4 sections seperated with by ;
        1;$((Get-Date).tostring());Catch;$($_.Exception)
        1 - The placement of the error physically inside the script.
        2 - The date and time of the error
        3 - What type of error
        4 - Information about the error

        Run this command inside a scheduled task every 5 minutes to copy files needed to required locations. Make sure the
        tasks running user has full access right to the file locations provided.
    .LINK
        https://bolding.us
    #>
    [cmdletbinding()]
    param (
        [Parameter(HelpMessage = "Source Folder", Mandatory = $True)][string[]]$SourceFolder,
        [Parameter(HelpMessage = "Target Folders", Mandatory = $True)][string[]]$TargetFolder,
        [parameter(HelpMessage = "Recurse the Source Folder")][switch]$Recruse
        [parameter(HelpMessage = "Log Location")][string]$Logs = "C:\tmp\SHDMoveFileLog.txt"
    )
    #Tests to see if local c:\tbc exists, if it doesn't, it will create the path.
    if (Test-Path (Split-Path $logs)) { "" >> $logs } else { mkdir (Split-Path $logs) }

    #Start with the first source
    foreach ($Source in $SourceFolder) {

        #Tests to see if the source path exists.
        if (Test-Path -Path $Source) {

            #Grabs the required files from the first source path. It only grabs files.
            #Also checks if there is a recruse flag. If so, recurses accordingly.
            if ($Recruse) { $files = Get-childitem -Path $Source -File -Recurse } else { $files = Get-childitem -Path $Source -File }

            #Next we sort through the files in question
            foreach ($File in $files) {

                #Create a test bool.
                $success = $false

                #Starts the target folder sorting
                foreach ($Target in $TargetFolder) {

                    #Tests to see if target folder exists. If not, logs.
                    if (Test-Path -Path $target) {

                        #Enter a try catch to copy the files
                        try {

                            #Copys a single file to target folder. Overwrites any other there without confirmation
                            #No Confiramtion due to the lack of human Interaction.
                            Copy-Item -Path $file.fullname -Destination $Target -Force -Confirm:$false

                            #If no error so far, sets the success bool to true
                            $success = $true
                        }
                        catch {

                            #a failure occured, thus we set the success bool to false
                            $success = $false

                            #We log the error. This is the first log that shows up in the system.
                            #We date it.
                            #We state it's a catch
                            #Then we give the reason the try catch gives.
                            "1;$((Get-Date).tostring());Catch;$($_.Exception)" >> $logs
                        }
                    }
                    else {
                        #We log the fact that we can't reach the target location
                        "2;$((Get-Date).tostring());CanNotFind;$Target" >> $logs
                    }
                }
                #We test the bool for success.
                if ($success -eq $true) {
                    try {

                        #if successful we remove the file.
                        Remove-Item -Path $file.FullName -Force -Confirm:$false
                    }
                    catch {

                        #If we can't remove the file we log the reason why.
                        "3;$((Get-Date).tostring());Catch;$($_.Exception)" >> $logs
                    }
                }
            }
        }
        else {
            #We log the fact we can't reach the source location.
            "4;$((Get-Date).tostring());CanNotFind;$Source" >> $logs
        }
    }
}

Examples

./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder\' -TargetFolder 'C:\tbc\tmp\Target Folder\','C:\tbc\tmp\Target Folder 2\'

Moves all files from the source folder 1 to target folders 1 and 2. This is good for a backup of files. What I use this for is a custom software at work. It other products drop to location 1. Then it has a backup folder and the system folder. There we go, good as gold.

./Invoke-SHDMoveFiles -SourceFolder 'C:\tbc\Tmp\Source Folder 1\','C:\tbc\Tmp\Source Folder 2\','C:\tbc\Tmp\Source Folder 3\'  -TargetFolder 'C:\tbc\tmp\Target Folder\' -Logs c:\tmp\Combiner.txt

Moves all files from the source folder 1, 2, and 3 to the target folder. It also logs any errors. This is useful when trying to come folders together.

Notes

  • This script was designed to be ran as a task. If it doesn’t grab a file the first time around, it will grab it the second time around. It does this by using the try catch. It trys to move a file. if it doesn’t, it logs it and leaves it. We do that because a lot of times these files are being created and have a lock state. It’s best not to move them during that state.
  • This script auto logs into the c:\tmp location if you don’t state otherwise when things go wrong.