Use PowerShell to Set Microsoft SQL Database Owner

$owner='CAP\SQL Admins'
$databaseName='TestDb'
$sqlServer=$env:computername

function setDbOwner{
  param(
    $principle=$env:USERDOMAIN+'\Domain Admins',
    $databaseName='TestDB',
    $sqlServer
  )
  
  function includeSqlTools{
    $ErrorActionPreference='stop'
    try{
      $trustedPsgallery=(Get-PSRepository PSGallery).InstallationPolicy -eq 'Trusted'
      if(!$trustedPsgallery){
          Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 
      }
      if(!(Get-Module sqlserver)){
          Install-Module sqlserver -Confirm:$False
      }
      if(!(Get-Module dbatools)){
          Install-Module dbatools -Confirm:$False
      }
      Import-Module sqlserver  
      Import-Module dbatools
      return $true
    }catch{
      write-warning $_
      return $false
    }
  }

  try{
    if(!(includeSqlTools)){
      write-warning "Cannot proceed with SQL Tools"
      return $false
    }
    $server=New-Object ('Microsoft.SqlServer.Management.Smo.Server') $sqlServer
    $db=New-Object Microsoft.SqlServer.Management.Smo.Database
    $db=$server.Databases.Item($databaseName)
    $db.SetOwner($principle, $TRUE)
    $db.Alter()
    return $true
  }catch{
    Write-Warning
    return $false
  }
}

setDbOwner $owner $databaseName $sqlServer

Use PowerShell to Grant SysAdmin Role to Certain Users

$principle=$env:USERDOMAIN+'\Domain Admins'
$sqlServer=$env:computername

function includeSqlTools{
  $ErrorActionPreference='stop'
  try{
    $trustedPsgallery=(Get-PSRepository PSGallery).InstallationPolicy -eq 'Trusted'
    if(!$trustedPsgallery){
        Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 
    }
    if(!(Get-Module sqlserver)){
        Install-Module sqlserver -Confirm:$False
    }
    if(!(Get-Module dbatools)){
        Install-Module dbatools -Confirm:$False
    }
    Import-Module sqlserver  
    Import-Module dbatools
    return $true
  }catch{
    write-warning $_
    return $false
  }
}

function grantSysadmin($principle,$sqlServer=$env:computername){
    if(!(includeSqlTools)){
        write-warning "Unable to proceed without SQL Tools"
        return $false
    }
    $sqlPortOpen=test-netconnection $sqlServer -port 1433 -informationlevel quiet
    $result=.{if($sqlPortOpen){
      try{
        $server=New-Object ('Microsoft.SqlServer.Management.Smo.Server') $sqlServer
        $sysadmins=$server.Roles|?{$_.Name -eq 'sysadmin'}
        $sysadmins.AddMember($principle)
        write-host "Current sysadmin principles:`r`n$(($sysadmins.EnumMemberNames()|out-string).trim())"
        return $true
      }catch{
        Write-Warning
        return $false
      }
    }else{
      # Workaround for firewall issues blocking SQL port between jump host and SQL Server
      invoke-command -computername $sqlServer {
        param($principle,$includeSqlTools)
        $sqlTools=[scriptblock]::create($sqlTools).invoke()
        if(!$sqlTools){
          write-warning "Unable to proceed without SQL Tools"
          return $false
        }
        try{
          $server=New-Object Microsoft.SqlServer.Management.Smo.Server("(localhost)")
          $sysadmins=$server.Roles|?{$_.Name -eq 'sysadmin'}
          $sysadmins.AddMember($principle)
          write-host "Current sysadmin principles:`r`n$(($sysadmins.EnumMemberNames()|out-string).trim())"
          return $true
        }catch{
          write-warning $_
          return $false
        }
      } -Args $principle,${function:includeSqlTools}
    }
  }
  return $result   
}

grantSysadmin $principle $sqlServer

PowerShell: Auto Login to WordPress and Update Gold Prices WooCommerce Plugin

# API URI - these are examples, only
$goldPriceApi='https://dragoncoin.com/XAU/USD'
$silverPriceApi='https://dragoncoin.com/XAG/USD'
$platinumApi='https://dragoncoin.com/XPT/USD'
$palladiumApi='https://dragoncoin.com/XPD/USD'

# WordPress WooCommerce Gold Price Plugin
$username='someadminaccount'
$password='somepassword'
$goldPriceFieldId='woocommerce_gold_price_options_24'
$agFieldId='woocommerce_gold_price_options_22'
$ptFieldId='woocommerce_gold_price_options_18'
$pdFieldId='woocommerce_gold_price_options_14'
$submitButtonClass='button-primary'
$expectedPageTitle='Gold Prices and Gold Products*'
$goldPricePage="https://dragoncoin.com/wp-admin/admin.php?page=woocommerce_gold_price"
$updateSeconds=120

# Other variables
$countDown=0
$timesToDeterminePause=5
$pauseSeconds=3600

function autologinSe{
    param(
        $url,
        $username,
        $password,
        $usernameElementId='user_login',
        $passwordElementId='user_pass',
        $submitButtonId='wp-submit',
        $exitIeWhenDone=$false
    )
    $ErrorActionPreference = 'continue'

    # Initial validation
    if(!$url){write-warning "No URL specified.";return $false}

    function killInternetExplorer{
        $ieInstances=(New-Object -COM 'Shell.Application').Windows()|?{$_.Name -like '*Internet Explorer*'} 
        $ieInstances|%{$_.Quit()
        [Runtime.Interopservices.Marshal]::ReleaseComObject($_)
        }
        [GC]::Collect()
        [GC]::WaitForPendingFinalizers()
        }

    function enableIeProtectedMode{
        # $hives = 0..4|%{"HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\$_"}
        $hives = 0..4|%{"HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\$_"}
        $keyName='2500' # Key Name '2500' corresponds to 'Protected Mode' in IE
        
        #Skipping zone 0 as that is the default local machine zone
        $hives[1..4]|%{Set-ItemProperty -Path $_ -Name $keyName -Value 0}
        $keys=$hives|%{Get-ItemProperty -Path $_}|select DisplayName, `
                                                        @{name='status';e={
                                                                        if($_.$keyName -eq 0){'enabled'}
                                                                        elseif($_.$keyName -eq 3){'disabled'}
                                                                        else{'n/a'}                                                                                        
                                                                        }}
        write-host "IE Protected Mode Standardized Values:`r`n$($keys|out-string)" 
    }

    function disableIeProtectedMode{
        # $hives = 0..4|%{"HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\$_"}
        $hives = 0..4|%{"HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\$_"}
        $keyName='2500' # Key Name '2500' corresponds to 'Protected Mode' in IE
        
        #Skipping zone 0 as that is the default local machine zone
        $hives[1..4]|%{Set-ItemProperty -Path $_ -Name $keyName -Value 3}
        $keys=$hives|%{Get-ItemProperty -Path $_}|select DisplayName, `
                                                        @{name='status';e={
                                                                        if($_.$keyName -eq 0){'enabled'}
                                                                        elseif($_.$keyName -eq 3){'disabled'}
                                                                        else{'n/a'}                                                                                        
                                                                        }}
        write-host "IE Protected Mode Standardized Values:`r`n$($keys|out-string)" 
    }

    function allowActiveX($zone='Trusted'){
        #Source: http://support.microsoft.com/KB/182569
        $zoneCode=switch($zone){
            'My Computer'{0;break}
            'Local Intranet'{1;break}
            'Trusted'{2;break}
            'Internet'{3;break}
            'Restricted Sites'{4;break}
            default{2}
            }
        #Reference table:
        #Value    Setting
        #------------------------------
        #0        My Computer
        #1        Local Intranet Zone
        #2        Trusted sites Zone
        #3        Internet Zone
        #4        Restricted Sites Zone
        $hashMap=@{
            '2702'=0 #ActiveX controls and plug-ins: Allow ActiveX Filtering = Enable (2702)
            '1208'=0 #ActiveX controls and plug-ins: Allow previously unused ActiveX controls to run without prompt = Enable (1208)
            '1209'=0 #ActiveX controls and plug-ins: Allow Scriptlets = Enable (1209)
            '2201'=3 #ActiveX controls and plug-ins: Automatic prompting for ActiveX controls = Disable (2201)
            '2000'=0 #ActiveX controls and plug-ins: Binary and script behaviors = Enable (2000)
            '120A'=0 #Display video and animation on a webpage that does not use external media player = Enable (120A)
            '1001'=0 #ActiveX controls and plug-ins: Download signed ActiveX controls = Enable (1001)
            '1004'=0 #ActiveX controls and plug-ins: Download unsigned ActiveX controls = Enable (1004)
            '1201'=0 #ActiveX controls and plug-ins: Initialize and script ActiveX controls not marked as safe for scripting = Enable (1201)
            '120B'=3 #Only allow approved domains to use ActiveX without prompt = Disable (120B)
            '1200'=0 #ActiveX controls and plug-ins: Run ActiveX controls and plug-ins = Enable (1200)
            '1405'=0 #ActiveX controls and plug-ins: Script ActiveX controls marked as safe for scripting = Enable (1405)
            }        
        
        $trustedDomains="HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\zones\$zoneCode"
        $currentValues=Get-ItemProperty $trustedDomains
        foreach ($item in $hashMap.GetEnumerator()) {
            $key = $item.Key
            $value = $item.Value
            if($currentValues.$key -ne $value){
                    New-ItemProperty -Path $trustedDomains -Name $key -Value $value -PropertyType DWORD -Force
                }
        }
    }

    function addDomainToTrustedSites($url){
        $httpType=.{[void]($url -match '^(https{0,1})');$matches[1]}
        $domain=([uri]$url).Host
        #$rootDomain=$domain.split('.')[-2..-1] -join '.' # This is assuming that the TLD is one-dotted (e.g. .com) not two-dotted (e.g. co.uk)
        $rootDomain=.{$fragments=$domain.split('.')
                    $fragments[1..$($fragments.count)] -join '.'
                    }
        write-host "Root domain detected`t: $rootDomain"        
        # The more advanced function to retrieve this value is at https://kimconnect.com/powershell-extract-root-domain-from-url
        if ($rootDomain -notmatch '\.' -or $rootDomain -eq $env:USERDNSDOMAIN){
            write-host "There's no need to add $url to the Trusted zone as it is local to this domain."
            return $true
            }
        $dwordValue=2 # value of true correlates to 'enable'
        $domainRegistryPath='HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains'
        $domainRegistryPath2='HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains' #EscDomains key applies to those protocols that are affected by the Enhanced Security Configuration (ESC)
        $null=New-Item -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap' -ItemType File -Name 'EscDomains' -Force
        $null=New-Item -Path "$domainRegistryPath" -ItemType File -Name "$rootDomain" -Force
        $null=New-Item -Path "$domainRegistryPath2" -ItemType File -Name "$rootDomain" -Force
        $null=Set-ItemProperty -Path "$domainRegistryPath\$rootDomain" -Name $httpType -Value $dwordValue
        $null=Set-ItemProperty -Path "$domainRegistryPath2\$rootDomain" -Name $httpType -Value $dwordValue

        # Also add {about:blank} record as that doesn't seem to have been added by default
        if (!(test-path "$domainRegistryPath\blank")){
            #New-ItemProperty -Path $trustedDomains -Name $key -Value $value -PropertyType DWORD -Force
            $null=New-Item -Path "$domainRegistryPath" -ItemType File -Name 'blank'
            $null=Set-ItemProperty -Path "$domainRegistryPath\blank" -Name 'about' -Value $dwordValue
            }
        if (!(test-path "$domainRegistryPath2\blank")){
            $null=New-Item -Path "$domainRegistryPath2" -ItemType File -Name 'blank'
            $null=Set-ItemProperty -Path "$domainRegistryPath2\blank" -Name 'about' -Value $dwordValue
            }                     

        # Also add {about:internet} record since it will stop a login when missing
        if (!(test-path "$domainRegistryPath\internet")){
            $null=New-Item -Path "$domainRegistryPath" -ItemType File -Name 'internet'
            $null=Set-ItemProperty -Path "$domainRegistryPath\internet" -Name 'about' -Value $dwordValue
            }
        if (!(test-path "$domainRegistryPath2\internet")){
            $null=New-Item -Path "$domainRegistryPath2" -ItemType File -Name 'internet'
            $null=Set-ItemProperty -Path "$domainRegistryPath2\internet" -Name 'about' -Value $dwordValue
            } 
            
        $valueAfterChanged=(Get-ItemProperty "$domainRegistryPath\$rootDomain")."$httpType"
        $value2AfterChanged=(Get-ItemProperty "$domainRegistryPath2\$rootDomain")."$httpType"
        if ($valueAfterChanged -eq 2 -and $value2AfterChanged -eq 2 ){
            write-host "$rootDomain has been added to Internet Explorer"
            return $true
            }
        else{
            write-warning "$rootDomain has NOT been added to Internet Explorer."
            return $false
            }
    }

    function includeSelenium{
        Import-Module Selenium -ea SilentlyContinue
        if (!(get-module selenium -EA SilentlyContinue)){
            Start-job {
                [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
                if(!(Get-PackageProvider Nuget -ea SilentlyContinue)){Install-PackageProvider -Name NuGet -Force}
                # Defining $ENV:ChocotaleyInstall so that it would be called by refreshenv
                $ENV:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.."   
                Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
                Install-Module Selenium -Force -Confirm:$False
                } |Receive-Job -Wait
            Update-SessionEnvironment
            Import-Module Selenium
            }
        }

    function invokeSelenium($url,$userName,$password,$usernameElementId,$passwordElementId,$submitButtonId){
        $ErrorActionPreference = "Stop"
        function closeSelenium($selenium){
            if($selenium){
                $selenium.close()
                $selenium.quit()
                }
            }
        
        function noLogin($url){
            $seleniumIe = New-Object "OpenQA.Selenium.IE.InternetExplorerDriver"
            $seleniumIe.Navigate().GoToURL($url)
            $title=$seleniumIe.Title
            write-host "Page reached: '$title'"
            $trustedSiteError=$title -match '^Error'
            if($trustedSiteError){
                write-host "An site trust issue has been detected. Adding root domain to the trusted sites list to resolve this issue."
                addDomainToTrustedSites $url              
                closeSelenium $seleniumIe                
                return $false
                }
            else{
                return $seleniumIe                
                }
            }

        function login($url,$username,$password,$usernameElementId,$passwordElementId,$submitButtonId){
            $seleniumIe = New-Object "OpenQA.Selenium.IE.InternetExplorerDriver"
            $seleniumIe.Navigate().GoToURL($url)
            $userField=$seleniumIe.FindElementById($usernameElementId)
            $userField.clear()
            $userField.SendKeys($username)
            $passwordField=$seleniumIe.FindElementById($passwordElementId)
            $passwordField.SendKeys('')
            $passwordField.clear()           
            $passwordField.SendKeys($password)
            $submitButton=$seleniumIe.FindElementById($submitButtonId)
            $submitButton.Click()
            $title=$seleniumIe.Title
            write-host "Page reached: '$title'"
            $trustedSiteError=$title -match '^Error'
            if($trustedSiteError){
                write-warning "A site trust issue has been detected."                
                closeSelenium $seleniumIe                
                return $false
            }else{
                return $seleniumIe                
                }
            }
        
        try{
            $null=allowActiveX
            $isLogin=$userName,$password,$usernameElementId,$passwordElementId,$submitButtonId|?{!(!$_)}
            if($isLogin){
                write-host "Login to $url as $userName..."
                $ie=login $url $userName $password $usernameElementId $passwordElementId $submitButtonId
            }else{
                write-host "Accesing $url without login..."
                $ie=nologin $url
                }
            return $ie
            }
        catch{            
            Write-Warning $Error[0].Exception.Message
            return $false
            }
        }

    try{
        write-host "Username`t: $username`r`nPassword`t: $(!(!$password))`r`nusernameElementId`t: $usernameElementId`r`npasswordElementId`t: $passwordElementId`r`nsubmitButtonId`t: $submitButtonId"
        $null=includeSelenium
        $null=disableIeProtectedMode
        $null=addDomainToTrustedSites $url                   
        if(get-module selenium -ea SilentlyContinue){
            $isLogin=$userName,$password,$usernameElementId,$passwordElementId,$submitButtonId|?{!(!$_)}
            if($isLogin){                
                $selenium=invokeSelenium $url $userName $password $usernameElementId $passwordElementId $submitButtonId
            }else{
                write-host "No username or password are given. Proceeding to access only the provided URL."
                $selenium=invokeSelenium $url
                }
        }else{
            write-warning "Please manually verify that the Selenium module is installed before retrying this function."
            }
        if($selenium){            
            if($exitIeWhenDone){
                $null=killInternetExplorer
                return $true
            }else{
                return $selenium
                }
        }else{
            write-warning "There were errors preventing a successful login."
            return $false
            }
        }
    catch {
        write-warning "$_"        
        return $false
        }
    
    # Note on a common error:
    #New-Object : Exception calling ".ctor" with "0" argument(s): "Unexpected error launching Internet Explorer. Protected
    #Mode settings are not the same for all zones. Enable Protected Mode must be set to the same value (enabled or
    #disabled) for all zones. (SessionNotCreated)"
    #At line:1 char:15
    #+ $seleniumIe = New-Object "OpenQA.Selenium.IE.InternetExplorerDriver"
    #+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    #    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
    # Solution: either DISABLE or ENABLE Protected mode for ALL ZONES
}

function getMetalPrice{
    param(
        $metalName='gold',
        $metalPriceApi
    )
    $priceData=Invoke-RestMethod $metalPriceApi
    $price=[math]::round(($priceData.spreadProfilePrices.ask | Measure-Object -Average).Average,2)
    write-host "$(get-date) --- $metalName price is $price"
    return [hashtable]@{
        $metalName=$price
    }
}

function updateFieldValues{
    param(
        $ie,
        $fieldId,
        $value
    )
    $field=$ie.FindElementById($fieldId)
    $field.clear()
    $field.SendKeys($value)
}

function updateMetalPrices{
    Do{
        if($countDown -lt $timesToDeterminePause){
            $changesDetected=$false
            $prices=$null
            $title=$ie.Title
            if($title -notlike $expectedPageTitle){
                $null=get-process iexplore | stop-process -force
                $ie=autoLoginSe $goldPricePage $username $password
                if($ie.Title -ne $expectedPageTitle){$ie.Navigate().GoToURL($goldPricePage)}
                clear-Host
                write-host "Connected to $goldPricePage"
            }
            $goldPrice=getMetalPrice 'gold' $goldPriceApi
            $silverPrice=getMetalPrice 'silver' $silverPriceApi
            $platinumPrice=getMetalPrice 'platinum' $platinumApi
            $palladiumPrice=getMetalPrice 'palladium' $palladiumApi
            $prices=$goldPrice+$silverPrice+$platinumPrice+$palladiumPrice
            if(!$goldPrice){
                write-warning "Cannot update if gold price value is Null"
            }elseif($previousAuPrice -ne $goldPrice){
                updateFieldValues $ie $goldPriceFieldId $prices.gold
                $changesDetected=$true
            }else{
                write-host "Gold prices haven't changed."
            }
            if(!$silverPrice){
                write-warning "Cannot update if silver price value is Null"
            }elseif($previousAgPrice -ne $silverPrice){
                updateFieldValues $ie $agFieldId $prices.silver
                $changesDetected=$true
            }else{
                write-host "Silver prices haven't changed."
            }
            if(!$platinumPrice){
                write-warning "Cannot update if gold price value is Null"
            }elseif($previousPtPrice -ne $platinumPrice){
                updateFieldValues $ie $ptFieldId $prices.platinum
                $changesDetected=$true
            }else{
                write-host "Platinum prices haven't changed."
            }
            if(!$palladiumPrice){
                write-warning "Cannot update if gold price value is Null"
            }elseif($previousPdPrice -ne $palladiumPrice){
                updateFieldValues $ie $pdFieldId $prices.palladium
                $changesDetected=$true
            }else{
                write-host "Palladium prices haven't changed."
            }
            if($changesDetected){
                $submitButton=$ie.findElementByClassName($submitButtonClass)
                $submitButton.Click()
                $countDown=0
            }else{
                $countDown++
            }
            $previousAuPrice=$goldPrice
            $previousAgPrice=$silverPrice
            $previousPtPrice=$platinumPrice
            $previousPdPrice=$palladiumPrice
            write-host "time-out $updateSeconds seconds until next iteration"
            Start-Sleep -s $updateSeconds
        }else{
            Start-Sleep -s $pauseSeconds
            $countDown=0
        }
    }until($false)
}

updateMetalPrices

WordPress: Gold Price Widget CSS

Here’s a sample of CSS Code to customize the display of the WordPress’ Gold Pricing Plugin:

.widget_block {
  padding: 0px !important;
  margin: 0px !important;
  border: 0px !important;
  }
  .r1 {
  width: 24.9%  !important;
  }
  .r2 {
  width: 24.9%  !important;
  }
  .r3 {
  width: 24.9%  !important;
  }
  .r4 {
  width: 24.9%  !important;
  }
  .metal-price {
  animation: blinker 10s linear infinite;
  color: red !important;
  }
  @keyframes blinker {
    50% {
      opacity: 0;
    }
  }
  .date {
  background-color: white !important;
  color: black !important;
  }

PowerShell: Remove IP Address Assignment Using Bluecat API

$bluecatUri='http://bluecat.kimconnect.com/Services/API'
$bluecatUsername='svc-bluecat-api'
$bluecatPassword='PASSWORD'
$configId=17
$ipv4Address='10.10.162.54'
$marker='toBeDeleted-'

function confirmation($content,$testValue="I confirm",$maxAttempts=3){
  $confirmed=$false;
  $attempts=0;        
  $content|write-host
  write-host "Please review this content for accuracy.`r`n"
  while ($attempts -le $maxAttempts){
      if($attempts++ -ge $maxAttempts){
          write-host "A maximum number of attempts have reached. No confirmations received!`r`n"
          break;
          }
      $userInput = Read-Host -Prompt "Please type in this value => $testValue <= to confirm. Input CANCEL to skip this item";
      if ($userInput.ToLower() -eq $testValue.ToLower()){
          $confirmed=$true;
          write-host "Confirmed!`r`n";
          break;                
      }elseif($userInput -like 'cancel'){
          write-host 'Cancel command received.'
          $confirmed=$false
          break
      }else{
          cls;
          $content|write-host
          write-host "Attempt number $attempts of $maxAttempts`: $userInput does not match $testValue. Try again or Input CANCEL to skip this item`r`n"
          }
      }
  return $confirmed;
}
function loginBluecat{
  param(
    [Parameter(Mandatory=$true)]$uri,
    [Parameter(Mandatory=$true)]$username,
    [Parameter(Mandatory=$true)]$password
  )
  $proxy = New-WebServiceProxy -Uri "$($uri)?wsdl"
    $proxy.url = $uri
    $cookieContainer = New-Object System.Net.CookieContainer
    $proxy.CookieContainer = $cookieContainer
    $proxy.login($username, $password)
  return $proxy
}

function removeIpv4Assignment{
  param(
    [Parameter(Mandatory=$true)]$proxy,
    [Parameter(Mandatory=$true)]$configId,
    [Parameter(Mandatory=$true)]$ipV4Address,
    [string]$marker='toBeDeleted-'
  )
  
  $erroractionpreference='stop'
  try{    
    $record=$proxy.getIP4Address($configId,$ipV4Address)
    if($record.id -eq 0){
      write-host "IP Address $ipv4Address does not exist in config ID $configId"
      return -1
    }else{
      $markedRecord=$marker+$record.name
      $record.Name=$markedRecord
      $proxy.update($record)
      $property=$proxy.searchByObjectTypes($markedRecord, "IP4Address", 0, 1)
      $confirmed=confirmation "Delete this record:`r`n$(($property|out-string).trim())"
      if($confirmed){
        $proxy.delete($property.id)
        return 0
      }else{
        write-host "User cancelled operation. IP Address $ipv4Address NOT removed."
        return 1
      }      
    }
  }catch{
    write-warning $_
    return 1
  }  
}

$bluecatProxy=loginBluecat -Uri $bluecatUri -Username $bluecatUsername -Password $bluecatPassword
removeIpv4Assignment -proxy $bluecatProxy -configId $configId -ipv4Address $ipV4Address

PowerShell: Unjoin Computer From Domain

$computername='testwindows'
$adminUsername='intranet\testadmin'
$adminPassword='PASSWORD'
$workgroup='Archive'

function unjoinComputerFromDomain{
    param(
        $computername,
        $adminUsername,
        $adminPassword,
        $workgroup='Archive'
        )
  $adminCred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminUsername,$(ConvertTo-SecureString $adminPassword -AsPlainText -Force)
  $psSession=try{
    $psOptions=New-PSSessionOption -OpenTimeout 300 -CancelTimeout 300
    new-pssession -computername $computername -Credential $adminCred -SessionOption $psOptions
    write-host "Connected to $computername..."
  }catch{
    write-warning $_
    $false
  }
  if($psSession.State -eq 'Opened'){
    try{
        $result=invoke-command -session $psSession -scriptblock{
            param ($adminUsername,$adminPassword,$workgroup)
            if ((gwmi win32_computersystem).partofdomain -eq $true) {
                $userdomain=$env:USERDNSDOMAIN
                $encryptedPassword=$(ConvertTo-SecureString $adminPassword -AsPlainText -Force)
                Set-LocalUser -name Administrator -Password $encryptedPassword
                write-host "The local 'Administrator' account password has been reset to be the same as the password of user $adminUsername"
                $adminCred=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminUsername,$encryptedPassword
                try{
                    Remove-Computer -UnjoinDomaincredential $adminCred -PassThru -Verbose -Restart -WorkgroupName $workgroup -Force
                    write-host "$env:computername has been removed from $userdomain"
                    return $true
                }catch{
                    write-warning $_
                    return $false
                }
            }else{
                write-host "$env:computer is NOT joined to any domain. No actions taken."
                return $true
            }      
        } -Args $adminUsername,$adminPassword,$workgroup -EA Stop
        $nullRemove-PSSession -ID $psSession.ID
        return $result
    }catch{
        write-warning $_
        $null=Remove-PSSession $psSession
        return $false
    }    
  }else{
    write-host "Unable to connect to $computername..."
    return $false
  }
}

unjoinComputerFromDomain $computername $adminUsername $adminPassword

Excel Visual Basic For Application (VBA): Determine IP List

Set objExcel = CreateObject("Excel.Application")

objExcel.Visible = True

intRow = 2

 

Set Fso = CreateObject("Scripting.FileSystemObject")

Set objWorkbook = objExcel.Workbooks.Open("C:\File_Name.xls")

Set InputFile = objWorkbook

Do Until objExcel.Cells(intRow,1).Value = ""

strComputer = objExcel.Cells(intRow, 1).Value

 

objExcel.Cells(1, 1).Value = "Machine Name"

objExcel.Cells(1, 2).Value = "IP Address"

objExcel.Cells(1, 3).Value = "Status"

 

On Error Resume Next

Set objWMIService = GetObject("winmgmts:\\" &  strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")

For Each objItem in colItems

If Err.Number <> 0 Then

objExcel.Cells(intRow, 2).Value = ""

objExcel.Cells(intRow, 3).Value = "Off Line"

Err.Clear

Else

objExcel.Cells(intRow, 2).Value = objItem.IPAddress

objExcel.Cells(intRow, 3).Value = "On Line"

End If

Next

intRow = intRow + 1

Loop

 

objExcel.Range("A1:C1").Select

objExcel.Selection.Interior.ColorIndex = 19

objExcel.Selection.Font.ColorIndex = 11

objExcel.Selection.Font.Bold = True

objExcel.Cells.EntireColumn.AutoFit

Set objWorkbook = Nothing

 

MsgBox "Done"

PowerShell: Function to Get Group Members as a Bypass Orphanated SID Errors

Problem:

[TESTSERVER]: PS C:\Users\administrator> Get-LocalGroupMember 'Remote Desktop Users'

Get-LocalGroupMember : Failed to compare two elements in the array.
    + CategoryInfo          : NotSpecified: (:) [Get-LocalGroupMember], InvalidOperationException
    + FullyQualifiedErrorId : An unspecified error occurred.,Microsoft.PowerShell.Commands.GetLocalGroupMemberCommand

[TESTSERVER]: PS C:\Users\administrator> Add-LocalGroupMember -group 'Remote Desktop Users' -member intranet\testuser
Add-LocalGroupMember : Principal intranet\testuser was not found.
    + CategoryInfo          : ObjectNotFound: (portal\nbsingh:String) [Add-LocalGroupMember], PrincipalNotFoundExcepti
   on
    + FullyQualifiedErrorId : PrincipalNotFound,Microsoft.PowerShell.Commands.AddLocalGroupMemberCommand

Workaround:

$servers = "localhost"
$groupName = 'Remote Desktop Users'

function getGroupMembers{
  param(
    $servers='localhost',
    $groupName='Administrators'
  )
  $members=@()
  foreach ($server in $servers){
      $group = [ADSI]"WinNT://$Server/$groupName"
      $groupMembers = @($group.Invoke('Members') | ForEach-Object {([ADSI]$_).path})
      $members+=$groupMembers
  }
  return $members
}

getGroupMembers $servers $groupName

CSS: How To Set Color Gradient and Animation to Text and Background

// Static color gradient
.colorGradientClass {
    background-color: #ffffff !important;
    background-image: linear-gradient(315deg, #ffffff 0%, #d9d9d9 74%)  !important;
}

// Animated color gradient
.colorTransitionClass {
    background-image: 
        linear-gradient(to right, transparent, white),
        linear-gradient(to right,yellow, white, yellow, white);
    background-size: 100% 100%, 2000% 100%;
    animation: move 5s infinite;
}
@keyframes move {
 from {background-position: center center, left center;}
 to {background-position: center center, right center;}
}

// This will result in blinking text
.blinkingText {
    animation: blinker 5s linear infinite;
    color: red !important;
}
@keyframes blinker {
  50% {
    opacity: 0;
  }
}

PowerShell: Check RPC Reachability of Remote Computer

# This is an ancient script that would work with PowerShell versions 2 to 5, but it won't work with version 6

  function checkRpc($server){
    #  WORKFLOW QUERIES THE PASSED ARRAY OF PORTS TO DETERMINE STATUS
    workflow Check-Port {
    param ([string[]]$RPCServer,[array]$arrRPCPorts)
    $comp = hostname

    ForEach -parallel ($RPCPort in $arrRPCPorts){
    $bolResult = InlineScript{Test-NetConnection -ComputerName $Using:RPCServer -port $Using:RPCPort -InformationLevel Quiet}
    If ($bolResult){
    Write-Output "$RPCPort on $RPCServer is reachable"
    }Else{
    Write-Output "$RPCPort on $RPCServer is unreachable"
    }
    }
    }
    #  INITIAL RPC PORT
    $strRPCPort = "135"
    #  MODIFY PATH TO THE PORTQRY BINARY IF NECESSARY
    $strPortQryPath = "C:\Sysinternals"
    #  TEST THE PATH TO SEE IF THE BINARY EXISTS
    If (get-command portqry.exe){
    $strPortQryCmd = "PortQry.exe -e $strRPCPort -n $Server"
    }Else{
    Write-Output "Could not locate Portqry.exe"
    Exit
    }
    #  CREATE AN EMPTY ARRAY TO HOLD THE PORTS RETURNED FROM THE RPC PORTMAPPER
    $arrPorts = @()
    #  RUN THE PORTQRY COMMAND TO GET THE EPHEMERAL PORTS
    $arrQuryResult = Invoke-Expression $strPortQryCmd
    # CREATE AN ARRAY OF THE PORTS
    ForEach ($strResult in $arrQuryResult)
    {
    If ($strResult.Contains("ip_tcp"))
    {
    $arrSplt = $strResult.Split("[")
    $strPort = $arrSplt[1]
    $strPort = $strPort.Replace("]","")
    $arrPorts += $strPort
    }
    }
    #  DE-DUPLICATE THE PORTS
    $arrPorts = $arrPorts | Sort-Object |Select-Object -Unique
    #  EXECUTE THE WORKFLOW TO CHECK THE PORTS
    Check-Port -RPCServer $Server -arrRPCPorts $arrPorts
  }

checkRpc remotecomputername

Linux: Bash Shell Script To Move/Archive Old Files

# create a script to move files (notice the regex escape for special chars)
sudo cat << EOF > /usr/local/sbin/movefiles
#!/bin/bash
sourceDirectory="\$1"
moveTo="\$2"
olderThan="\$3"
find \$sourceDirectory -name "*"  -type f -mtime +\$olderThan -print0 | while IFS= read -r -d '' file; do mv \$file \$moveTo; done
EOF

# Mark the file with executable permissions
sudo chmod +x /usr/local/sbin/movefiles

# Create a new entry in cron
sudo crontab -e
 
# Insert these new lines
0 2 * * * /usr/local/sbin/movefiles /home/path/tosource/ /path/todestination/ 30 > /dev/null

PowerShell: Create and Edit SMB Shares

# Create SMB Share
$sharePath='C:\testshare'
$accessList="$env:USERDOMAIN\Domain Admins","NT AUTHORITY\Authenticated Users"
$shareName=split-path $sharePath -leaf
mkdir $sharePath
New-SmbShare -Name $shareName -Path $sharePath -FullAccess $accessList

# Check SMB Acccesses
[SMBSERVER]: PS C:\Users\kimconnect\Documents> Get-SmbShareAccess $shareName
Name          ScopeName AccountName                      AccessControlType AccessRight
----          --------- -----------                      ----------------- -----------
testshare *         KIMCONNECT\Domain Admins         Allow             Full
testshare *         NT AUTHORITY\Authenticated Users Allow             Full

# Add Share Permissions
$grantPrinciple="$env:USERDOMAIN\Domain Admins"
Grant-SmbShareAccess -Name $shareName -AccountName $grantPrinciple -AccessRight Full -Force

# Remove Share Permissions
$removePrinciple="NT AUTHORITY\Authenticated Users"
Revoke-SmbShareAccess -Name $shareName -AccountName $removePrinciple -Force

# Clone NTFS Access Control List (ACL)
# Warning: only do this to a new clone-to directory as misuse can cause permission problems
$cloneAclFrom='C:\originalshare'
$cloneAclTo=$sharePath
get-acl $cloneAclFrom|set-acl $cloneAclTo

# Check NTFS Permissions:
[SMBSERVER]: PS C:\Users\kimconnect\Documents> (get-acl c:\testshare).AccessToString
Everyone Allow  ReadAndExecute, Synchronize
CREATOR OWNER Allow  FullControl
NT AUTHORITY\SYSTEM Allow  FullControl
BUILTIN\Administrators Allow  FullControl
KIMCONNECt\TestAdmin Allow  FullControl

PowerShell: Allow Log On To Remote Desktop Service

# editWindowsSecurity.ps1
# Version 0.0.1
# Notes:
# - This has NOT been thoroughly tested. Microsoft Windows version variances may render this script ineffective
# - need to add a routine to translate SID into principle name as part of the matching sequence
#
# WARNING: Do Not Use Mis-use This as It Can Brick Your Windows!
# No implied or express warranties shall be assumed. Caveat Emptor!


function editWindowsSecurity{
  param(
    $principle="Remote Desktop Users",
    $privilege="SeRemoteInteractiveLogonRight",
    $operation='add' # or 'remove'
  )

  $originalSecurity='C:\originalSecurity.inf'
  $newSecurity='C:\newSecurity.inf'
  $originalDb='c:\windows\security\database\secedit.sdb'
  $securityDb='C:\originalSecurity.sdb'
  $log='C:\security.log'

  try{
    $null=get-process mmc -ea Ignore|stop-process
    cp $originalDb $securityDb -ea Stop
  }catch{
    write-warning $_
    return $false
  }
  #secedit /export /db $securityDb /mergedpolicy /cfg $originalSecurity /log $log /quiet

  $null=secedit /export /areas USER_RIGHTS /cfg $originalSecurity
  $null="[Unicode]`r`nUnicode=yes`r`n`r`n[Version]`r`nsignature=`"`$CHICAGO`$`"`r`nrevision=1`r`n`r`n[Privilege Rights]"|Out-File $newSecurity -Force -WhatIf:$false 
  $originalRights=Get-Content $originalSecurity
  $applyChanges=$false

  if($operation -eq 'add'){
    write-host "Adding $principle to $privilege..."
    foreach($line in $originalRights){ 
        if($line -like "$privilege`*"){
            write-host "Before: $line"
            $line=$line+",$principle"
            write-host "After: $line"
            $line|Out-File $newSecurity -Append -WhatIf:$false
            $applyChanges=$true
        }
    }
  }elseif($operation -eq 'remove'){
    write-host "Removing $principle from $privilege..."
    $security=$originalRights|?{$_ -match "^$privilege"}
    if($security){
      $list=[regex]::match($security,'=\s(.*)').captures.groups[1].value
      $newList=($list -split ','|?{$_ -notmatch "$principle"}) -join ','
      $line="$privilege = $newList"
      if($line -ne $security){
        write-host "Before: $security`r`nAfter:$line"
        $line|Out-File $newSecurity -Append -WhatIf:$false
        $applyChanges=$true
      }else{
        write-host "No changes."
      }
    }
  }else{
    write-warning "Please specify operation type as either ADD or REMOVE"
  }

  if($applyChanges){
    try{
      $output=SECEDIT /configure /db $securityDb /cfg $newSecurity /log $log
      write-host $output
    }catch{
      write-warning $_
      return $false
    }    
  }  
  #Remove-Item $originalSecurity -Force -WhatIf:$false
  #Remove-Item $newSecurity -Force -WhatIf:$false
}

PowerShell: Overcome Issues with Error 13932 in SCVMM When Refreshing Virtual Machines

Dealing with Clusters

# refreshCluster.ps1
# Function to refresh a cluster in VMM in anticipation of errors with unregistered SMB/CIFS shares

$clustername='cluster-101.kimconnect.com'
$runasAccount='domain\hyperv-admin'

function refreshCluster($clusterName,$runasAccount){    
  # Function to Register FileShare to a Cluster in SCVMM
  function registerFileShareToCluster{
    param(
      $clustername,
      $fileSharePath,
      $runasAccount
    )
    $ErrorActionPreference='Stop'
    try{
      Import-Module -Name "virtualmachinemanager"
      # Preempt this error
      # Error (26193)
      # No Run As account is associated with the host
      if($runasAccount){
        $runas = Get-SCRunAsAccount -Name $runasAccount
        $hostCluster = Get-SCVMHostCluster -Name $clustername
        Set-SCVmHostCluster -VMHostCluster $hostCluster -VMHostManagementCredential $runas
      }
      <# Got this error
      Set-SCVmHostCluster : A Hardware Management error has occurred trying to contact server
      :n:CannotProcessFilter :HRESULT 0x8033801a:No instance found with given property values. .
      WinRM: URL: [http://serverFQDN:5985], Verb: [INVOKE], Method: [AddToLocalAdminGroup], Resource:
      [http://schemas.microsoft.com/wbem/wsman/1/wmi/root/scvmm/AgentManagement]
      (Error ID: 2927, Detailed Error: Unknown error (0x8033801a))
  
      Check that WinRM is installed and running on server. For more information use the command
      "winrm helpmsg hresult" and http://support.microsoft.com/kb/2742275.
  
      To restart the job, run the following command:
      PS> Restart-Job -Job (Get-VMMServer localhost | Get-Job | where { $_.ID -eq })
      At line:1 char:1
      + Set-SCVmHostCluster -VMHostCluster $hostCluster -VMHostManagementCred ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : ReadError: (:) [Set-SCVMHostCluster], CarmineException
          + FullyQualifiedErrorId : 2927,Microsoft.SystemCenter.VirtualMachineManager.Cmdlets.SetHostClusterCmdlet
      #>
      <# preempt this error:
      Register-SCStorageFileShare : A parameter cannot be found that matches parameter name 'VMHostManagementCredential'.
      At line:1 char:87
      + ... ePath -VMHostCluster $hostCluster -VMHostManagementCredential $runasA ...
      +                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : InvalidArgument: (:) [Register-SCStorageFileShare], ParameterBindingException
          + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.SystemCenter.VirtualMachineManager.Cmdlets.RegisterSCSt
        orageFileShareCmdlet
      #>
      Register-SCStorageFileShare -FileSharePath $fileSharePath -VMHostCluster $hostCluster
      <# This error can safely be ignored
      Error (26233)
      Capacity/Free space cannot be calculated for \\NAS\CIFSSHARE. Failed to retrieve information with Win32 error code 64.
      #>  
  
      # This snippet is to register the SMB server onto VMM as a resource. It's optional
      # $servername='servername'
      # $shareName='test'
      # $addedShare = Get-SCStorageFileShare -Name "$servername\$sharename"
      # Register-SCStorageFileShare -StorageFileShare $addedShare -VMHostCluster $hostCluster
      # Set-SCVMHostCluster -RunAsynchronously -VMHostCluster $hostCluster -VMHostManagementCredential $runas
      return $true
    }catch{
      write-warning $_
      return $false
    }
  
  }
  # $clustername='CLUSTER-9999'
  # $fileSharePaths=@(
  #   '\\FILESERVER01\SHARE01',
  #   '\\FILESERVER01\SHARE02'
  # )
  # $runasAccount='domain\hyperv-admin'
  # foreach($fileSharePath in $fileSharePaths){  
  #   $success=registerFileShareToCluster $clusterName $fileSharePath $runasAccount
  #   if($success){
  #     write-host "$fileSharePath added successfully" -ForegroundColor Green
  #   }else{
  #     write-host "$fileSharePath was NOT added" -ForegroundColor Yellow
  #   }
  # }
  
  #Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager
  Import-Module -Name "virtualmachinemanager"
  #$guestVMs=Get-ClusterResource -cluster $clustername|?{$_.resourcetype.name -eq 'virtual machine'}
  $guestVMs=Get-ClusterGroup -Cluster $clustername|?{$_.GroupType -eq 'VirtualMachine'}
  foreach ($vm in $guestVMs){
      #[string]$vmName=$_.OwnerGroup.Name
      $vmName=$vm.Name
      $status=((Get-SCVirtualMachine -Name $vmName).StatusString|out-string).trim()
      if($status -notmatch 'Stopped|Running' -and !(!$status)){
          try{            
            try{
              Read-SCVirtualMachine $vmName -EA Stop
              write-host "$vmName refresh initiated." -ForegroundColor Green
            }catch [Microsoft.VirtualManager.Utils.CarmineException]{
              $errorMessage=$_
                $smbPath=[regex]::match($errorMessage,'\\\\(.*)\\').Value
                if($smbPath){
                    write-host "Add this SMB/CIFS path the cluster: $smbPath"
                    $smbRegistered=registerFileShareToCluster $clustername $smbPath $runasAccount
                    if($smbRegistered){
                      $null=Refresh-VM -VM $vmName -RunAsynchronously -Force;
                      write-host "$vmName refresh initiated." -ForegroundColor Yellow
                      #$null=Read-SCVirtualMachine -vm $vmName -Force -RunAsynchronously; # This statement missed 'stopped' VMs
                    }else{
                      write-warning "Unable to register $smbPath"
                    }
                }else{
                  write-host $errorMessage
                }
            }
          }catch{
            write-host $_
          }
      }else{
          write-host "$vmName status $(if($status){$status}else{'Unknown'})." -ForegroundColor Gray         
      }
    }
}
refreshCluster $clustername $runasAccount

Dealing with Individual Hyper-V Hosts

# refreshHost.ps1
$hostName='hyperv-2000.kimconnect.com'
$runasAccount='domain\hyperv-admin'

function refreshHost($hostname,$runasAccount){
  
  # Sub-routine to add Share Path to Hyper-V Host
  function addFileSharePathToHost($hostName,$sharePath,$runasAccount){
    try{
      $vmHost = Get-SCVMHost -ComputerName $hostName -EA Stop
      Register-SCStorageFileShare -FileSharePath $sharePath -VMHost $vmHost -EA Stop
      return $true
    }catch [Microsoft.VirtualManager.Utils.CarmineException]{
      $errorMessage=$_
      if($errorMessage -like "*Error ID: 26193*"){
        $runas = Get-SCRunAsAccount -Name $runasAccount
        Set-SCVmHost -VMHost $vmHost -VMHostManagementCredential $runas
        Register-SCStorageFileShare -FileSharePath $sharePath -VMHost $vmHost
        return $true
      }else{
        write-warning "$errorMessage"
        return $false
      }
    }catch{
      write-warning $_
      return $false
    }
    #Set-SCVMHost -VMHost $vmHost -RunAsynchronously -BaseDiskPaths $sharePath #-VMPaths "C:\ProgramData\Microsoft\Windows\Hyper-V"
  }
  
  $unsupportedSharedFiles=Get-SCVMHost $hostname | Get-SCVirtualMachine | ? {$_.Status -eq 'UnsupportedSharedFiles'} | Select Name,State,VMHost
  foreach($vmName in $unsupportedSharedFiles.Name){
    try{
      Read-SCVirtualMachine $vmName -EA Stop
      write-host "$vmName refresh initiated." -ForegroundColor Green
    }catch [Microsoft.VirtualManager.Utils.CarmineException]{
      $errorMessage=$_
        $smbPath=[regex]::match($errorMessage,'\\\\(.*)\\').Value
        if($smbPath){
            write-host "Add this SMB/CIFS path the cluster: $smbPath"
            $smbRegistered=addFileSharePathToHost $hostname $smbPath $runasAccount
            if($smbRegistered){
              $null=Refresh-VM -VM $vmName -RunAsynchronously -Force;
              write-host "$vmName refresh initiated." -ForegroundColor Yellow
              #$null=Read-SCVirtualMachine -vm $vmName -Force -RunAsynchronously; # This statement missed 'stopped' VMs
            }else{
              write-warning "Unable to register $smbPath"
            }
        }else{
          write-host $errorMessage
        }
    }
  }  
}
refreshHost $hostName $runasAccount

PowerShell: Try Catch Technique to Obtain Error Type

# Test

try{
Read-SCVirtualMachine $vmName -EA Stop
}catch{
$errorMessage=$error[0].Exception.GetType().FullName
write-host $errorMessage
}

# Get error type

Microsoft.VirtualManager.Utils.CarmineException

# Retry catch with specific error type

try{
Read-SCVirtualMachine $vmName -EA Stop
}catch [Microsoft.VirtualManager.Utils.CarmineException]{
$errorMessage=$_
$smbPath=[regex]::match($errorMessage,'\\\\(.*)\\').Value
if($smbPath){
write-host "Add this SMB/CIFS path the cluster: $smbPath"
}else{
write-host $errorMessage
}
}

PowerShell: Initiate Tests on Certain Ports

function initTestPort($portNumber=5985,$maxTests=3){

  function getIndexDifference {
    param(
      [String] $string1,
      [String] $string2
    )
    if ( $string1 -ceq $string2 ) {
      return -1
    }
    for ( $i = 0; $i -lt $string1.Length; $i++ ) {
      if ( $string1[$i] -cne $string2[$i] ) {
        return $i
      }
    }
    return $string1.Length
  }  

  $baseLine=(netstat -ano -p tcp|select-string "$portNumber"|out-string).trim()
  if(!$baseline){
      write-warning "$env:computername doesn't have any service listening on port $portNumber"
      exit
  }else{
      write-host "$env:computername is now listening on port $portNumber"
      do{
          $status=(netstat -ano -p tcp|select-string "$portNumber"|out-string).trim()
          if($status -ne $baseline){
            $maxTests--  
            $matchIndex=getIndexDifference $status $baseline
            $difference=$status.Substring($matchIndex).Trim()
            write-host "$maxTests remaining => $difference"
            $status=$baseline
            $null=ping 127.0.0.1 -n 1
          }
      }until(!$maxTests)
  }
}
# Test reachability from a client machine
$server='nameOrIpHere'
$port=5985
(new-object Net.Sockets.TcpClient).Connect($server, $port)

PowerShell: How To Test A Server Ephemeral Port

# Setup a listening port on server
# This session will automatically terminates after a number of test counts

function initTestEpheralPort{
  param(
    $port=59848,
    $testCount=3
  )
  $cmdlet="(new-object Net.Sockets.TcpClient).Connect('$env:computername', $port)"
  write-host "$env:computername is now listening on port $port"
  write-host "Please run this function at the client side:`r`n$cmdlet"
  $listener=[System.Net.Sockets.TcpListener]$port;
  $listener.Start();
  while($testCount) 
  {    
      $clientAccepted=$listener.AcceptTcpClient();
      if($clientAccepted){
          write-host "$((netstat -ano -p tcp|select-string "$port"|out-string))"
          $testCount--;
          Write-Host "Connection test $testCount remains!";   
      }
      $clientAccepted.Close();
      if(!$testCount){
          # Stop listening on the server
          $listener.Stop();
          write-host "Tests have completed."  
      }
  }
}

initTestEpheralPort 59848
# Test reachability from a client machine
$server='nameOrIpHere'
$port=59848
(new-object Net.Sockets.TcpClient).Connect($server, $port)

PowerShell: Compare File Counts of 2 Directories

$folder1='C:\Temp'
$folder2='C:\Temp2'
$username=$null
$password=$null

function compareFileCounts{
  param($folder1,$folder2,$mountAsUser,$mountAsPassword)
  function mountPathAsDrive($path,$driveLetter,$mountAsUser,$mountAsPassword){

    function convertPathToUnc($path,$computername=$env:computername,$credentials=$null){
      $pathIsUnc=$path -match '^\\\\'
      $pathIsReachable=if($credentials){test-path $path -credentials $credentials}else{test-path $path}
      if($pathIsUnc -and $pathIsReachable){
          return $path
      }elseif(!$pathIsUnc){
          $convertedPath=.{
                      $x=$path -replace "^([a-zA-Z])\:","\\$computername\`$1`$";
                      if($x -match '\\$'){return $x.Substring(0,$x.length-1)}else{return $x}
                      }
          $validUnc=if($convertedPath){test-path $convertedPath -ErrorAction SilentlyContinue}else{$false}
          if($validUnc){
              write-host "$path has been converted to $convertedPath, and it is reachable"
              return $convertedPath
          }else{
              write-warning "$path has been converted to $convertedPath, but it is NOT unreachable"
              return $null
          }            
      }else{
          write-warning "Path is invalid"
          return $null
      }
    }

    $pathIsUnc=$path -match '^\\\\'
    $credentials = if($mountAsUser -and $mountAsPassword){
          $password = "$mountAsPassword" | ConvertTo-SecureString -AsPlainText -Force
          New-Object System.Management.Automation.PSCredential ("$mountAsUser", $password )
      }else{
          $null
      }
    $driveLetter=if($driveLetter){
      $driveLetter
    }else{
      $unavailableDriveLetters=(Get-Volume).DriveLetter|sort
      $availableDriveLetters=.{(65..90|%{[char]$_})|?{$_ -notin $unavailableDriveLetters}}
      [char]($availableDriveLetters[0])
    }

    if($pathIsUnc){
      if($credentials){
          $null=net use "$driveLetter`:" "$path" /user:$mountAsUser "'$mountAsPassword'"
      }else{
          $null=net use "$driveLetter`:" "$path"
      }      
    }else{
        $pathAsUnc=convertPathToUnc $path
        if($credentials){
          $null=net use "$driveLetter`:" "$pathAsUnc" /user:$mountAsUser "'$mountAsPassword'"
        }else{
          $null=net use "$driveLetter`:" "$pathAsUnc"
        }
    }

    $reachable=if($credentials){test-path "$driveLetter`:\" -credentials $credentials}else{test-path "$driveLetter`:\"}
    return $(if($reachable){"$driveLetter`:\"}else{$false})
  }

  $unavailableDriveLetters=(Get-Volume).DriveLetter|sort
  $availableDriveLetters=.{(65..90|%{[char]$_})|?{$_ -notin $unavailableDriveLetters}}
  $firstDriveLetter=[char]($availableDriveLetters[0])
  $secondDriveLetter=[char]($availableDriveLetters[1])

  $path1=mountPathAsDrive $folder1 $firstDriveLetter $mountAsUser $mountAsPassword
  $path2=mountPathAsDrive $folder2 $secondDriveLetter $mountAsUser $mountAsPassword

  if($path1 -and $path2){
    $timer1=[System.Diagnostics.Stopwatch]::StartNew()
    $filesInFolder1 = Invoke-Expression -Command:"cmd.exe /C dir '$path1' /S /B /W /A:-D" -EA Ignore
    $filesCount1=$filesInFolder1.Count
    $elapsed1=[math]::round($timer1.Elapsed.TotalMinutes,2)
    $timer1.Stop()
    write-host "$folder1 (mounted as $path1) file count: $filesCount1 ($elapsed1 minutes)"
    $timer2=[System.Diagnostics.Stopwatch]::StartNew()
    $filesInFolder2 = Invoke-Expression -Command:"cmd.exe /C dir '$path2' /S /B /W /A:-D" -EA Ignore
    $filesCount2=$filesInFolder2.Count
    $elapsed2=[math]::round($timer2.Elapsed.TotalMinutes,2)
    $timer2.Stop()
    write-host "$folder2 (mounted as $path2) file count: $filesCount2 ($elapsed2 minutes)"
  }elseif(!$path1 -and !$path2){
    write-warning "Both $path1 and $path2 are NOT accessible."
  }elseif(!$path1){
    write-warning "$path1 is NOT accessible."
  }elseif(!$path2){
    write-warning "$path2 is NOT accessible."
  }
  $null=net use "$($path1[0]):" /delete
  $null=net use "$($path2[0]):" /delete
  write-host "Total duration: $($elapsed1+$elapsed2) minutes"
  return $($filesCount1 -eq $filesCount2)
}

compareFileCounts $folder1 $folder2 $username $password
# old version

$folder1='\\FILESERVER1\TEST'
$folder2='\\BACKUP1\TEST'

function compareFileCounts($folder1,$folder2){
    $filesInFolder1 = Invoke-Expression -Command:"cmd.exe /C dir '$folder1' /S /B /W /A:-D" -EA Ignore
    $fileCount1=$filesInFolder1.Count
    write-host "$folder1 file count: $fileCount1"
    $filesInFolder2 = Invoke-Expression -Command:"cmd.exe /C dir '$folder2' /S /B /W /A:-D" -EA Ignore
    $fileCount2=$filesInFolder2.Count
    write-host "$folder2 file count: $fileCount2"
    return $($fileCount1 -eq $fileCount2)    
}

compareFileCounts $folder1 $folder2

PowerShell: Query Google Account Using GAM

$emailAddress='someone@yourcompany.com'
$field='accounts:last_login_time'

function getGamUser{
    param(
        $emailAddress,
        $field
    )

    $result=try{gam report users user $emailAddress}catch{}
    if($result){
        $headers=$result[0] -split ','
        $index=$headers.IndexOf($field)
        return ($result[1] -split ',')[$index]
    }else{
        write-warning "$emailAddress field $field has not matched anything"
        return $null
    }
}

getGamUser $emailAddress $field

PowerShell: Disable Windows Hello

function disableWindowsHello{
    $regHive='REGISTRY::HKLM\SOFTWARE\Policies\Microsoft\PassportForWork'
    $refreshEnv=$false    
    if (!(Test-Path $regHive)){
        Write-Host "Creating registry path $regHive"
        New-Item -Path $regHive -Force
    }
    if ((get-itemproperty $regHive -EA Ignore).Enabled -ne 0){
        New-ItemProperty -Path $regHive -Name 'Enabled' -Value 0 -PropertyType DWORD -Force
        $refreshEnv=$true
    }
    if ((get-itemproperty $regHive -EA Ignore).DisablePostLogonProvisioning -ne 1){
        New-ItemProperty -Path $regHive -Name 'DisablePostLogonProvisioning' -Value 1 -PropertyType DWORD -Force
        $refreshEnv=$true
    }
    if($refreshEnv){
        write-host 'refreshing environment...'
        & 'RUNDLL32.EXE' USER32.DLL, UpdatePerUserSystemParameters 1, True
    }
    write-host "Windows Hello has been disabled on $env:computername"
}
disableWindowsHello