Thursday, March 26, 2026
Back in the day it was possible to connect to a specific site on a specific ip, just by supplying the host header.
curl -v -H "Host: www.example.com" https://127.8.4.2
But with tls1.3 strict SNI checking, the host header isn’t enough.
It is, however, possible to override dns by using the –resolve override.
curl -v --resolve www.example.com:80:127.8.4.2 https://www.example.com
Friday, March 18, 2022
Executable is powershell.exe. Arguments:
-command "& { . "c:\location\to\script.ps1"; my_function_name }"
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
Wednesday, February 10, 2021
Authorize for teams.
Replace YOUR_TENANT_ID, YOUR_EMAIL and YOUR_PASSWORD.
Use one of these client_id’s, depending on your usecase.
1fec8e78-bce4-4aaf-ab1b-5451cc387264 (Teams mobile/desktop application)
5e3ce6c0-2b1f-4285-8d4b-75ee78787346 (Teams web application)
auth.sh:
#!/bin/bash
curl -s -X POST https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/token \
-c cookies.txt \
-o auth.blob \
-F grant_type=password \
-F resource=https://teams.microsoft.com/ \
-F client_id=1fec8e78-bce4-4aaf-ab1b-5451cc387264 \
-F username=YOUR_EMAIL \
-F password=YOUR_PASSWORD
This will save your bearer token, amongst others, to auth.blob in a json object.
Because the bearer token is only valid for a certain period of time, you’ll need to refresh it. Here’s how. You’ll need ‘jq’ installed to decompose the json object.
refresh.sh:
#!/bin/bash
REFRESHTOKEN=`cat auth.blob | jq ".refresh_token" | sed 's/"//g'`
curl -s -X POST https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/token \
-c cookies.txt \
-o auth.blob \
-F grant_type=refresh_token \
-F resource=https://teams.microsoft.com/ \
-F client_id=1fec8e78-bce4-4aaf-ab1b-5451cc387264 \
-F refresh_token=$REFRESHTOKEN
In the script you can keep repeating actions, but in order to keep your token active, you can use the following piece of code:
if [ -f "auth.blob" ]; then
EXPIRES=`cat auth.blob | jq ".expires_on" | sed 's/"//g'`
NOW=`date +%s`
TTL=`expr $EXPIRES - $NOW`
if [ $TTL -lt 60 ]; then
echo "time for a refresh!"
./refresh.sh
fi
else
echo "no previous auth present!"
./auth.sh
EXPIRES=`cat auth.blob | jq ".expires_on" | sed 's/"//g'`
NOW=`date +%s`
TTL=`expr $EXPIRES - $NOW`
fi
Now you can do the cool stuff like query your calendar or whatever:
#!/bin/bash
BEARER=`cat auth.blob | jq ".access_token" | sed 's/"//g'`
curl -s --write-out "%{http_code}|%{time_total}n" -o bla.txt "https://teams.microsoft.com/api/mt/emea/beta/me/calendarEvents?StartDate=2021-02-07T23:00:00.000Z&EndDate=2021-02-14T23:00:00.000Z" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Teams/1.3.00.30866 Chrome/80.0.3987.165 Electron/8.5.1 Safari/537.36" \
-H "authorization: Bearer $BEARER"
Or verify your local timezone:
#!/bin/bash
BEARER=`cat auth.blob | jq ".access_token" | sed 's/"//g'`
date "+%Y.%m.%e %T %N"
curl -v 'https://teams.microsoft.com/api/mt/part/emea-03/beta/me/calendarEvents/timeZoneSettingsWithOffset?timezone=Europe%2FAmsterdam' \
-H "authorization: Bearer $BEARER" \
-H 'authority: teams.microsoft.com'
echo ""
date "+%Y.%m.%e %T %N"
Wednesday, June 24, 2020
Example how to allow certain known connections (e.g. unifi accesspoints) and log unknown connection attempts.
This is done by adding a chain called LOGDROP, append packets that match the criteria (tcp/8080) to that chain, log the packets and drop them.
iptables:
#!/bin/bash
AP01="192.168.0.1"
AP02="192.168.0.2"
AP03="192.168.0.3"
# Resetting ...
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
iptables -X
# Setting default policy on incoming traffic
iptables -P INPUT DROP # DENY INCOMING CONNECTIONS
iptables -P FORWARD DROP # THIS IS NOT A ROUTER
# allowed accesspoints
iptables -A INPUT -p tcp --dport 8080 -s $AP01 -j ACCEPT # UNIFI - AP01
iptables -A INPUT -p udp --dport 3478 -s $AP01 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -s $AP02 -j ACCEPT # UNIFI - AP02
iptables -A INPUT -p udp --dport 3478 -s $AP02 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -s $AP03 -j ACCEPT # UNIFI - AP03
iptables -A INPUT -p udp --dport 3478 -s $AP03 -j ACCEPT
# log AP connections that aren't allowed
iptables -N LOGDROP
iptables -A INPUT -p tcp --dport 8080 -j LOGDROP
iptables -A LOGDROP -j LOG --log-prefix "IPTables-Dropped: " --log-level 7
iptables -A LOGDROP -j DROP
# Make persistent
iptables-save >/etc/iptables/rules.v4
Create a file in /etc/rsyslog.d/ called “30-unifi-accesspoints.conf” with the following content:
:msg,contains,"IPTables-Dropped: " /var/log/unifi_accesspoints.log
and restart rsyslog
Monday, August 25, 2014
After swapping a couple of defective harddisks, i was wondering why i never got a predictive failure from my Areca controller.
The weird thing is: the logging shows warnings:
2014-08-24 23:15:37 IDE Channel #08 Reading Error
2014-08-24 23:15:28 IDE Channel #08 Reading Error
2014-08-24 23:15:19 IDE Channel #08 Reading Error
2014-08-24 23:15:10 IDE Channel #08 Reading Error
However.. the controller doesn’t seem to do anything with the s.m.a.r.t. values.
Here’s a script you might want to use as a base to get your monitoring up and running.
#!/bin/bash
CLI="/path/to/cli32"
NR_OF_PORTS=`$CLI disk info | wc -l`
# subtract 4 to get rid of the formatting and determine the real number of disks
NR_OF_PORTS=`expr $NR_OF_PORTS - 4`
echo "Controller has $NR_OF_PORTS ports"
for (( i=1; i<=$NR_OF_PORTS; i++ ))
do
RELOC_SECT=`$CLI disk smart drv=$i | grep "Reallocated Sector Count" | awk '{print $9}'`
if [ -z "$RELOC_SECT" ]; then
echo "Port $i = No Disk"
else
echo "Port $i = $RELOC_SECT"
fi
done
Thursday, April 17, 2014
By default, powershell uses your regional settings. So when importing data from external files, a simple get-date or typecast to [DateTime] does not always give the correct value.
With the template below, you can interpret any format.
PS> $timeinfo = '12 07 2012 18 02'
PS> $template = 'HH mm yyyy dd MM'
PS> [DateTime]::ParseExact($timeinfo, $template, $null)
Samstag, 18. Februar 2012 12:07:00
Values can be:
d Day of month 1-31
dd Day of month 01-31
ddd Day of month as abbreviated weekday name
dddd Weekday name
h Hour from 1-12
H Hour from 1-24
hh Hour from 01-12
HH Hour from 01-24
m Minute from 0-59
mm Minute from 00-59
M Month from 1-12
MM Month from 01-12
MMM Abbreviated Month Name
MMMM Month name
s Seconds from 1-60
ss Seconds from 01-60
t A or P (for AM or PM)
tt AM or PM
yy Year as 2-digit
yyyy Year as 4-digit
z Timezone as one digit
zz Timezone as 2-digit
zzz Timezone
Friday, December 20, 2013
ping servername.domain.local -n 1 >NUL
if NOT %ERRORLEVEL%==0 GOTO OFFLINE
call \\servername.domain.local\share\Extra_Login_Stuff.bat
:OFFLINE
Monday, May 13, 2013
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 "-"
Tuesday, November 6, 2012
PS D:Usersxxx> (get-qaduser "myaccount").memberof.count
46
PS D:Usersxxx> (get-qaduser "myaccount").allmemberof.count
98
PS D:Usersxxx> (get-qaduser "myaccount").nestedmemberof.count
53
According to: http://msdn.microsof … ibrary/ms677943.aspx: “memberOf does not contain the user’s membership in domain local and global groups in other domains.”
Indeed, AllMemberOf shows these groups too (DomainLocal only in my example).
PS D:Usersxxx> $groups = (get-qaduser "myaccount").allmemberof
PS D:Usersxxx> foreach ($group in $groups)
{
(get-qadgroup $group).GroupScope
}
Global
Global
Global
DomainLocal
Global
Wednesday, September 5, 2012
All those ways to get the size of directories with powershell are extremely slow. Especially on network shares.
e.g.
$colItems = (Get-ChildItem C:Scripts | Measure-Object -property length -sum)
"{0:N2}" -f ($colItems.sum / 1MB) + " MB"
Currently i’m harvesting through roughly 40TB of data and it’s taking me daaaaaaaaaays!
So i’m in desperate need of something faster.
Then i thought about robocopy. Robocopy gives great statistics. So if i do a “dry-run” (list-only, not really copy), i might get the information i need by parsing the output.
Choice of switches:
- /b = backup mode. Supposed to give me access to every file
- /l = list only/dry-run, not really doing the copy
- /mir = action what you would normally do when you would copy the data. This also dives into all subdirectories.
- /r:0 = no retries
- /w:0 = don’t wait on anything
- /ns /nc /nfl /ndl /njh = no logging of any kind. We only want the summary.
Then we get this piece of code (it could be a lot shorter, but i’m keeping it readable):
function get_size_of_dir_in_bytes_with_robocopy ($directory)
{
write-host "- $directory" -foreground "GREEN"
[string]$result = robocopy /b /l /mir "$directory" "c:\whatever" /r:0 /w:0 /ns /nc /nfl /ndl /njh /bytes
if (!($lastexitcode -eq 16))
{
$pos = ($result).indexof("Bytes : ")
$start = $pos + 8
$length = $result.length
$end = $length - $start
$newstring = ($result).substring($start,$end)
$newstring = $newstring.trim()
echo $newstring.split()[0]
}
else
{
echo "CANNOT ACCESS"
}
}
Monday, December 12, 2011
In my case i’m migrating from a Kerio Mailserver that is presenting all the folders as a subfolder of inbox, hence the
--sep1 . --prefix1 inbox
Always start the commands with the “–dry” option to do a dry-run (test-run) first!
To migrate the inbox and all subfolders:
imapsync --syncinternaldates --useheader 'Message-Id' --buffersize 8192000 --nosyncacls --host1 oldhost.domain.com --user1 [email protected] --passfile1 passfile1.txt --ssl1 --host2 imap.gmail.com --user2 [email protected] --passfile2 passfile2.txt --ssl2 --authmech2 LOGIN --sep1 . --sep2 . --prefix1 inbox --folderrec INBOX
Sent items need a little bit of translation. “Sent Items” will be translated to “[Gmail]\Verzonden berichten” (Dutch language).
imapsync --syncinternaldates --useheader 'Message-Id' --buffersize 8192000 --nosyncacls --host1 oldhost.domain.com --user1 [email protected] --passfile1 passfile1.txt --ssl1 --host2 imap.gmail.com --user2 [email protected] --passfile2 passfile2.txt --ssl2 --authmech2 LOGIN --sep1 . --prefix1 inbox --folder "Sent Items" --regextrans2 's/Sent Items/\[Gmail\]\/Verzonden berichten/'
Wednesday, August 17, 2011
Oops, tested the previous script on a samba server. For some reason, testing the script on a Windows 2008 R2 domain resulted in an exception. So here“s the new script.
Check will output warnings in red to your screen, all the rest of the data will go to the logfile.
For best results, export to a .csv and open in excel. Then sort the first column.
Calling the script:
path_depth_analysis "G:mydirectory" >c:output.csv
The script:
function path_depth_analysis( $path )
{
$items = get-childitem $path
if (!($items.count) -eq 0)
{
foreach ($item in $items)
{
[int]$length_path = $path.length
[int]$length_item = $item.name.length
[int]$total_length = $length_path + $length_item
if ($total_length -gt 240)
{
$item_name = $item.name
write-host "! - $total_length - $path -> $item_name" -foreground RED
}
[string]$fullname = $item.FullName
[string]$type = $item.GetType().Name
if ($type -eq "FileInfo")
{
echo "$total_length;file;$fullname"
}
else
{
echo "$total_length;dir;$fullname"
path_depth_analysis "$fullname"
}
}
}
}
Friday, August 12, 2011
this script doesn’t seem to work correctly in a Windows-Windows environment, please go to test for files or directories exceeding Windows MAX_PATH (v2)
This week i was reading about a customer that needed an analysis of files or directories that were “too long”. As you may or may not know: if the full path to a file exceeds 260 characters, you may be running into troubles, as Windows does not handle that particularly well.
Microsoft’s article on that: http://msdn.microsof … 365247(v=vs.85).aspx
So i was thinking, how hard can that be? Let’s start powershell and write down a couple of lines …..
$maxpath=260
function testmaxpath($source)
{
$found_yet=0
$items = get-childitem $source -recurse
foreach ($item in $items)
{
$the_full_name = $item.fullname
$the_length = [string]$item.fullname.length
if ([int]$the_length -ge $maxpath)
{
write-host "$the_length $the_full_name" -foregroundcolor red
$found_yet++
}
}
echo "-----------------------------------"
echo " found $found_yet files/directories"
echo "-----------------------------------"
}
then just run it against a disk or share, e.g.
testmaxpath e:\data
or
testmaxpath \\192.168.1.5\share_x
That’ll give you a nice overview.
off topic:
if you really want to bug your system administrator, he’ll like this:
mkdir \\server\share\%username%\aaaaaaaaaaaaabbbbbbbbbbbbbbbbbbccccccccccccccccccddddddddddddddeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkkkkklllllllllllllllllmmmmmmmmmmmmmnnnnnnnnnnnnnn
subst h: \\server\share\%username%\aaaaaaaaaaaaabbbbbbbbbbbbbbbbbbccccccccccccccccccddddddddddddddeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkkkkklllllllllllllllllmmmmmmmmmmmmmnnnnnnnnnnnnnn
mkdir h:\aaaaaaaaaaaaabbbbbbbbbbbbbbbbbbccccccccccccccccccddddddddddddddeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkkkkklllllllllllllllllmmmmmmmmmmmmmnnnnnnnnnnnnnn
subst i: h:\aaaaaaaaaaaaabbbbbbbbbbbbbbbbbbccccccccccccccccccddddddddddddddeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkkkkklllllllllllllllllmmmmmmmmmmmmmnnnnnnnnnnnnnn
mkdir i:\aaaaaaaaaaaaabbbbbbbbbbbbbbbbbbccccccccccccccccccddddddddddddddeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkkkkklllllllllllllllllmmmmmmmmmmmmmnnnnnnnnnnnnnn
subst j: i:\aaaaaaaaaaaaabbbbbbbbbbbbbbbbbbccccccccccccccccccddddddddddddddeeeeeeeeeeeeeffffffffffffffffgggggggggggggggghhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkkkkklllllllllllllllllmmmmmmmmmmmmmnnnnnnnnnnnnnn
… and copy some files and set some weird acl’s on them.
Guess what will happen when he wants to delete those directories?
Oh boy, those were the days :)
Monday, June 20, 2011
Here’s an example:
On Error Resume Next
' #################################################
'Select the number of characters on the left that need to be checked
' Note the following situations:
' 10.150.9. <-- check on charleft=9 including trailing "."!
' 10.150.10
' 10.150.11
' or
' 10.150.99. <-- check on charleft=10 including trailing "."!
' 10.150.100
' 10.150.101
Const charleft = 10
' #################################################
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\" & ".\root\default:StdRegProv")
Set WSHShell = CreateObject("Wscript.Shell")
Set WSHNetwork = CreateObject("WScript.Network")
strKeyPath = "SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
DHCPAddress = WSHShell.RegRead("HKLM" & strKeyPath & subkey & "\DhcpIPAddress")
'Skip disconnected adapters and apipa addresses (failed dhcp)
If DHCPAddress <> "0.0.0.0" And Left(DHCPAddress,3) <> "169" Then
'wscript.echo "Interface " + subkey + " = " + DHCPAddress
TestOctet1 = left(DHCPAddress, int(charleft))
Select Case TestOctet1
case "10.150.123"
'location A with 1 ip range
WScript.Echo "this is location A"
'actions for location A
WSHNetwork.AddWindowsPrinterConnection "\\printserver\main_printer_location_A"
WSHNetwork.MapNetworkDrive "L:", "\\NT2000\data_location_A"
case "10.150.99.","10.150.101"
'location B with 2 ranges, note the first range with trailing "." because it's shorter
WScript.Echo "this is location B"
'actions for location A
WSHNetwork.AddWindowsPrinterConnection "\\printserver\main_printer_location_B"
WSHNetwork.MapNetworkDrive "L:", "\\NT2000\data_location_B"
case "192.168.2","10.150.102","10.234.234"
'location C with 3 ranges
WScript.Echo "this is location C"
'actions for location A
WSHNetwork.AddWindowsPrinterConnection "\\printserver\main_printer_location_C"
WSHNetwork.MapNetworkDrive "L:", "\\NT2000\data_location_C"
case "10.22.164","10.22.165"
'location D with 2 ranges
WScript.Echo "this is location D"
'actions for location A
WSHNetwork.AddWindowsPrinterConnection "\\printserver\main_printer_location_D"
WSHNetwork.MapNetworkDrive "L:", "\\NT2000\data_location_D"
End Select
End If
Next
Thursday, April 28, 2011
After cleaning up a userprofile on a Windows 7 station (Deleting folders “c:\users\MyUserAccount” and the roaming profile on “\\fs01\profiles\MyUserAccount”) i thought i would start with a clean profile.
But Windows kept logging user “MyUserAccount” in with a temporary profile.
It seems that Windows keeps a list of profile locations in the registry. If that location for a certain user can’t be found, the user is logged on with a temporary profile.
This is the key:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
What you see there is a lists of profile SID’s, so you have to check them all out to find your user and delete the whole key accordingly.
I thought it would be handy to write a script that automates this.
It checks for a key called “ProfileImagePath” and if the value in that key (e.g. c:\users\JohnDoe) doesn’t exist on the local system, it wipes the whole registry key from the ProfileList.
Save as W7ProfileListCleanup.vbs:
ON ERROR RESUME NEXT
'### GLOBAL VARIABLES
Dim WSHShell, oFSO, strComputer, ProfileListRegistryLocation, ArrayWithProfileSIDS, Subkeys, HKEY_LOCAL_MACHINE
'### CREATE OBJECTS
Set WSHShell = CreateObject("WScript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")
strComputer = "."
Set objRegistry = GetObject("winmgmts:\" & strComputer & "\root\default:StdRegProv")
'### CONSTANTS
HKEY_LOCAL_MACHINE = &H80000002
ProfileListRegistryLocation = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
RegistryKeyContainingPath = "ProfileImagePath"
'### FUNCTIONS NEEDED
Function CheckAndDelete(LocalProfileDir, ProfileSID, FullPath)
If not oFSO.FolderExists(LocalProfileDir) then
WScript.Echo "NOT FOUND: " + LocalProfileDir
DeleteProfileListKeyRecursive FullPath
else
WScript.Echo "OK: " + LocalProfileDir
end if
End Function
Function DeleteProfileListKeyRecursive(FullPath)
WSHShell.Run "reg delete ""HKLM" + FullPath + """ /f", 0, True
WScript.Echo "- Deleted: " + FullPath
End Function
'### END OF FUNCTIONS NEEDED
'### START THE ACTION
'### ENUMERATE THE LIST WITH PROFILES
objRegistry.EnumKey HKEY_LOCAL_MACHINE, ProfileListRegistryLocation, ArrayWithProfileSIDS
For Each ProfileSID In ArrayWithProfileSIDS
FullPath = ProfileListRegistryLocation & "" & ProfileSID
objRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, FullPath, RegistryKeyContainingPath, LocalProfileDir
'### CHECK FOR DIRS AND DELETE IF NOT FOUND
CheckAndDelete LocalProfileDir, ProfileSID, FullPath
Next
Thursday, October 14, 2010
If you have a printserver in your network and you want to change certain properties, e.g. print black/white instead of color, normally what you do is change the settings on the Advanced Tab - Default Settings Button. These are the settings a user inherits when first connecting to the shared printer.
But what if you want to revert these settings. You’d have to remove the printer from the userprofile and make sure the printer’s readded, in order to inherit the new default settings.
This is exactly what the following script does.
It also cleans removed/unshared printers, as it can only re-add printers that still exist.
on error resume next
Set WshNetwork = WScript.CreateObject("WScript.Network")
'## Enumerate all the current printers in the profile
Set oPrinters = WshNetwork.EnumPrinterConnections
For i = 0 to oPrinters.Count - 1 Step 2
'## Disconnect the printer
WshNetwork.RemovePrinterConnection ""& oPrinters.Item(i+1) &"", true, true
'## Readd the same printer (if still exists)
WshNetwork.AddWindowsPrinterConnection ""& oPrinters.Item(i+1) &"", true, true
Next
msgbox "Done"
You might want to comment the last line to make the script run totally silent.
Tuesday, March 16, 2010
Run from prompt:
for /f "tokens=*" %a in ('dir /b *.dll') do regsvr32 /s %a
Remember: when running from a batchfile %a becomes %%a
Thursday, September 10, 2009
One of my customers has a directory filled with home directories of all students.
Due to some copying, the ownership of all files was set to “administrator”.
Since quota was enabled, quota usage of all students was practically 0.
They needed a fix to set ownership back a.s.a.p.
I created the following batchfile. You need the subinacl utility from microsoft though.
- Put the script in the directory you want to make the changes for.
- Usernames must match the directorynames.
@echo off
for /f "tokens=*" %%a in ('dir /b /ad') do subinacl /file %%a\*.* /setowner=%%a
pause
Maybe you want to grant the users (just to be sure)
@echo off
for /f "tokens=*" %%a in ('dir /b /ad') do subinacl /file %%a\*.* /setowner=%%a
for /f "tokens=*" %%a in ('dir /b /ad') do subinacl /file %%a\*.* /grant=YOURDOMAIN\%%a
pause
Wednesday, September 9, 2009
Sometimes you just want people not to show up in your address list.
Here’s a simple vbs script that does the trick.
REM On Error Resume Next
groep = inputbox("Which group?")
set objRootDSE = GetObject("LDAP://RootDSE")
strdomainname = objRootDSE.Get("defaultNamingContext")
set objgroup = getobject("LDAP://cn=" + groep + ",cn=users," + strdomainname)
objgroup.GetInfo
arrmember = objgroup.GetEx("member")
for each objmember in arrmember
set objuser = getobject("LDAP://" + objmember)
objuser.MSExchHideFromAddressLists = TRUE
objuser.SetInfo
next