Friday, March 18, 2022

Run powershell specific function from task scheduler

Executable is powershell.exe. Arguments:

-command "& { . "c:\location\to\script.ps1"; my_function_name }"

Powershell speed hacks

Powershell can be painfully slow when dealing with larger arrays, reading files and listing large directories. Here are some workarounds.

Arrays
Slow:

$myarray = @()
foreach ($x in $y) {
  $myarray += $x
}

Much faster is working with an arraylist:

$myarray = [System.Collections.ArrayList]@()
foreach ($x in $y) {
  $null = $procarray.Add($x)
}

Reading files
Slow:

get-content $filename

Fast:

([System.IO.File]::ReadAllLines($filename))

Listing large directories
Slow:

$items = get-item "\\server\share\*.csv" | sort LastWriteTime

The fastest workaround i’ve been able to find is actually using a dos prompt. Use dir switches for sorting purposes.
Note: dir returns just text, while get-items returns objects with all sorts of properties. It depends on your use case whether this hack is actually usable or not.

$items = cmd /r dir "\\server\share\*.csv" /OD /B

Tuesday, October 5, 2021

Install Windows 11 without TMP 2.0

When Windows 11 complains about your system not being compliant:

  • press shift+F10
  • regedit
  • Navigate to HKEY_LOCAL_MACHINE\SYSTEM\Setup
  • new key: LabConfig
  • new dword value: BypassTPMCheck = 1
  • new dword vlaue: BypassSecureBootCheck = 1

Go back and resume the installation again.

Thursday, October 10, 2019

Win 10 slow startup caused by AMD Radeon graphics card

Reminder: Look in registry for EnableUPLS and set 1 to 0.

Friday, July 18, 2014

ParentContainer

Quest active directory powershell module has this nice property for user and computer objects: ParentContainer
Microsoft’s native ActiveDirectory module doesn’t.
I’m using this property a lot because it looks much more friendly than the CanonicalName.
Here’s a simple function to achieve the same.

function CanonicalName_to_ParentContainer ($cname)
{
  try
  { 
    $lastslash = $cname.lastindexof("/")
    $cname.substring(0,$lastslash)
  }
  catch
  {
    $cname
  }
}

Friday, May 9, 2014

Add Windows back to Grub2

My lifesaver:

create and chmod +x the file:

/etc/grub.d/15_Windows

Add this code:

#! /bin/sh -e
echo "Adding Windows" >&2
cat << EOF
menuentry "Windows" {
set root=(hd0,1)
chainloader +1
}
EOF

for grub2:

grub2-mkconfig -o /boot/grub2/grub2.cfg

or:

grub-mkconfig -o /boot/grub/grub.cfg

Friday, December 20, 2013

Batchfile loginscript domain check

ping servername.domain.local -n 1 >NUL
if NOT %ERRORLEVEL%==0 GOTO OFFLINE
  call \\servername.domain.local\share\Extra_Login_Stuff.bat
:OFFLINE

Tuesday, December 10, 2013

Powershell IP address computations

Very neat function for powershell ip computations:
source: technet

function Get-IPrange 
{ 
<#  
  .SYNOPSIS   
    Get the IP addresses in a range  
  .EXAMPLE  
   Get-IPrange -start 192.168.8.2 -end 192.168.8.20  
  .EXAMPLE  
   Get-IPrange -ip 192.168.8.2 -mask 255.255.255.0  
  .EXAMPLE  
   Get-IPrange -ip 192.168.8.3 -cidr 24  
#>  
  
  param  
  (   
    [string]$start,  
    [string]$end,  
    [string]$ip,  
    [string]$mask,  
    [int]$cidr  
  )  
  
  function IP-toINT64 () {  
    param ($ip)  
  
    $octets = $ip.split(".")  
    return [int64]([int64]$octets[0]*16777216 +[int64]$octets[1]*65536 +[int64]$octets[2]*256 +[int64]$octets[3])  
  }  
  
  function INT64-toIP() {  
    param ([int64]$int)  
 
    return (([math]::truncate($int/16777216)).tostring()+"."+([math]::truncate(($int%16777216)/65536)).tostring()+"."+([math]::truncate(($int%65536)/256)).tostring()+"."+([math]::truncate($int%256)).tostring() ) 
  }  
  
  if ($ip) {$ipaddr = [Net.IPAddress]::Parse($ip)}  
  if ($cidr) {$maskaddr = [Net.IPAddress]::Parse((INT64-toIP -int ([convert]::ToInt64(("1"*$cidr+"0"*(32-$cidr)),2)))) }  
  if ($mask) {$maskaddr = [Net.IPAddress]::Parse($mask)}  
  if ($ip) {$networkaddr = new-object net.ipaddress ($maskaddr.address -band $ipaddr.address)}  
  if ($ip) {$broadcastaddr = new-object net.ipaddress (([system.net.ipaddress]::parse("255.255.255.255").address -bxor $maskaddr.address -bor $networkaddr.address))}  
  
  if ($ip) {  
    $startaddr = IP-toINT64 -ip $networkaddr.ipaddresstostring  
    $endaddr = IP-toINT64 -ip $broadcastaddr.ipaddresstostring  
  } else {  
    $startaddr = IP-toINT64 -ip $start  
    $endaddr = IP-toINT64 -ip $end  
  }   
  
  for ($i = $startaddr; $i -le $endaddr; $i++)  
  {  
    INT64-toIP -int $i  
  } 
 
}

Monday, May 13, 2013

Dump Exchange mailbox permissions

A complete script to first dump all exchange mailboxes to .csv and then enumerate all mailbox permissions.
It uses the Exchange 2010 management shell and Quest’s Active Directory Powershell modules.

Usage:

  • Load the script in the ISE editor.
  • Set the two global parameters
  • Run the script
  • first execute: dump_mailboxes (this wil generate a .csv with all mailboxes)
  • then execuite: dump_all_mailbox_permission (this will generate a second .csv with all permissions. Open in Excel to filter)
echo "-"

$global_ad_domain = "AD.CUSTOMER.LOCAL"
$global_ad_short = "AD"

### Load Modules for Active Directory and Exchange 2010
if (!($QUEST_LOADED))
{
  Add-PSSnapin Quest.ActiveRoles.ADManagement
  Set-QADPSSnapinSettings -DefaultSizeLimit 0

  $logged_on_to = $env:USERDNSDOMAIN
  if (!($logged_on_to -eq "$global_ad_domain"))
  {
    $user = read-host "Enter username in adusername format"
    $pw = read-host "Enter password" -AsSecureString
    connect-QADService -service '$global_ad_domain' -ConnectionAccount $user -ConnectionPassword $pw
  }
  else
  {
    connect-QADService
  }
  
  Set-QADProgressPolicy -ShowProgress $false
  $QUEST_LOADED=$TRUE
  echo "quest loaded"
}

if ($EMS_loaded -eq $NULL)
{
  . 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
  echo "- Exchange Management Shell Loaded"
  Connect-ExchangeServer -auto
  $EMS_loaded = $true
  echo "- Exchange Management Shell Connected"
}

### Functions

function dump_mailboxes
{
  $output_file = "d:\temp\mailboxes.csv"
  echo "Name`tAlias" >$output_file
  # $mailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox
  $mailboxes = Get-Mailbox -resultsize Unlimited
  foreach ($mailbox in $mailboxes)
  {
    $Name = $mailbox.Name
    $Alias = $mailbox.Alias
    echo "$Name`t$Alias" >>$output_file
  }
}

function dump_all_mailbox_permission
{
  $output_file = "d:\temp\mailbox_permissions.csv"
  $lijst = import-csv -delimiter "`t" d:\temp\mailboxes.csv
  $aantal = $lijst.count
  $teller = 0
  write-host "Aantal functionele mailboxen: $aantal"
  echo "Mailbox`tAuthType`tGroup`tSam`tType" >$output_file  
  foreach ($regel in $lijst)
  {
    $teller++
    $Alias = $regel.alias
    write-host "$teller / $aantal -> $Alias"
    mailbox_permissions $Alias >>$output_file
  }
}

function mailbox_permissions($mailbox)
{
  if ($perms = get-mailboxpermission -identity "$mailbox" | where {($_.isinherited -eq $false) -and ($_.User -like "$global_ad_short\*")})
  {
    foreach ($perm in $perms)
    {
      $usr = $perm.User.tostring()
      $typeusr = (get-qadobject -identity $usr -DontUseDefaultIncludedProperties).type
      $usr = $usr.replace("$global_ad_short","")
      $rights = $perm.AccessRights
      if ($typeusr -eq "group")
      {
        $members = get-qadgroupmember -identity "$usr"
        foreach ($member in $members)
        {
          $mbmrsam = $member.samaccountname
          echo "$mailbox`t$typeusr`t$usr`t$mbmrsam`t$rights"
        }      
      }
      else
      {
        echo "$mailbox`t$typeusr`t`t$usr`t$rights"
      }
    }
  }
}

echo "-"

Monday, January 21, 2013

reset domain administrator password on a win2k8r2 DC

Forgot your domain admin password? Whoops.

On a Win2k8r2 domain controller:

  • Boot with the installation media (or any other WinPE kind of media)
  • Go to the System32 directory
  • ren utilman.exe utilman.exe.bak
  • copy cmd.exe utilman.exe
  • Reboot the system
  • At the logon screen, press Windows Key + U. A command prompt will start.
  • net user Administrator "!mynewpass123"
  • Log in, start a command prompt.
  • del utilman.exe
  • copy utilman.exe.bak utilman.exe

done :-)