Tag Archives: File Presence

Count homedirectories

For management purposes creating a report with the directory size of users’s home directory you can use this script. It will count the total size of the home directory per user. It will get the user’s name based on the name of the home directory. This wil be written down in the file.

$list = @(GCI "\\Fileserver\users$" -Force| ?{$_.PsIsContainer -eq $True})
$Header1 = ("DisplayName;Gebruikersnaam;Grootte in MB")
$Header2 = ("Hoofdmap;Grootte in MB")
$Path1 = ".\Overzicht-H-Schijven.csv"
AC -Value $Header1 -Path $Path1
$Path1 = GI $Path1


Foreach ($Item in $List)
{
$Result = @(GCI ($Item.FullName) -Recurse -Force)
[Int]$Count = 0
Foreach ($ResultItem in $Result){$Count = $Count + $ResultItem.Length / 1MB}
$Value = ((Get-ADUser $Item.Name).Name + ";" + $Item.Name+ ";" + $Count)
AC -Value $Value -Path $Path1
}

$Body = "Beste,

Hierbij het overzicht van de grootte van de H Schijven van de gebruikers van uw organisatie.

Groet,
"
$list = Import-CSV $Path1.FullName -Delimiter ";"
$list | % { $_."Grootte in MB" = [int]$_."Grootte in MB" }
$list = $list | Sort -Property Gebruikersnaam -Unique | Sort -Property "Grootte in MB" -Descending
$list | Export-CSV $Path1.FullName -Delimiter ";" -NoTypeInformation -Force

Send-MailMessage -From "servicedesk@company.nl" -Subject "Gebruiker overzicht " -To "emailadress@domain.tld" -Body $Body -SmtpServer "mailserver" -Attachments $Path1.FullName

RI $Path1 -Force

Repair autocomplete in Outlook with RES WM and Zero-profiling

Sometimes things that are meant to make your life easier make it harder. As is the case with RES Workspace Manager with Zero-profiling. If you have published Outlook 2010 or 2013 in RES Workspace Manager and you’ve enabled Zero-profiling fixing a corrupted Autocomplete dat file is not an easy job. Luckily there is a tool called Nk2edit. With NK2edit you can repair and edit NK2 and Autocomplete.dat files. The nice thing about NK2edit is that it has command line parameters. So in my case I made a little Powershell script that does the job.

When a user opens Outlook 2010 a couple of files are being loaded out of the Zero profile. They are loaded under C:\Users\$Username\Appdata\Local\Microsoft\Outlook. A file called Stream_Autocomplete_XXXXX.dat is created. In that file the is the autocomplete data stored. All you helpdesk have to do is enter the UNC path of that file in the script. Request the user to close Outlook and let the script do it’s thing. In the background you regenerate the autocomplete file by simple load and save it. This resolves the problem. To do so I let the /Script parameter refer to an empty script file. This manipulates nk2edit to load and save the .dat file. For the script to work you’ll need to download NK2edit.exe. You do not need a commercial license for the script to work, however if you use it commercially you of course do need one ;-).

$Choice = "y"
While ($Choice -eq "Y"){
[console]::ForegroundColor = "Cyan"
Write-Host "Vul de locatie van het autocomplete bestand:" -NoNewline
$Locatie = Read-host

$Result = Test-Path $Locatie
While ($Result -ne $True){Write-Host "De opgegeven locatie bestaat niet. Vul opnieuw in:" -NoNewline Cyan
$Locatie = Read-host
$Result = Test-Path $Locatie}

Write-host "NK2edit wordt uitgevoerd"
 .\NK2Edit.exe /nobackup /nofirstbackup /script .\Script.txt $Locatie
Start-Sleep -s 5
$Testresult = ((Get-date) - (GI $locatie ).LastWriteTime).Seconds
While ($Testresult -ne 15){ $Testresult = ((Get-date) - (GI $locatie ).LastWriteTime).Seconds
}
Write-host "NK2Edit is klaar"

$Choice = ""
While ($choice -notmatch "[y|n]"){$choice = read-host "Wilt u dit voor nog een user uitvoeren? (Y/N)"}
[console]::ResetColor()	
}

I compressed the script and NK2edit in a zip file. Click here to download.

App-v 4.6 large cache detection and alert script

App-v 4.6 generates sometime a large sftfs.fsd file. Users are experiencing performance issues when the file exceeds 15 GB. To fix this problem administrators remove the file by rebooting the Xenapp in safe mode. No user should be logged in of course. The Citrix servers therefore need to be empty. My colleagues ran a VB script that did the job of detecting but nothing else. I have made a script in Powershell that does the same but also set the server in ProhibitLogOns logon mode. The implement this script the server must have the Xenapp SDK installed. The server which runs the script need to have relay rights on the SMTP server. You’ll also need to have a Xenapp Server with PSRemoting enabled or the server itself should be member of the Xenapp farm.

#Load Modules and Snapins
Import-Module ActiveDirectory
Add-PSSnapin Citrix*
#Opens array for servers that apply on the conditions specified below
$ProhibitLogonServers =@()
$SMTP = "SMTPSERVER"
#Get all Xenapp server based on OU
$list = Get-ADComputer -Filter * -SearchBase "OU=Citrix Servers,OU=Servers,DC=Domain,DC=LOCAL"
Foreach ($Computer in $List){$Server = $Computer.DNSHostName 
$Result = GI "\\$Server\d$\AppVClientcache\Global\SoftGrid Client\sftfs.fsd"
If ($result.length -ne 0){$Outinfo = $Server+";"+$Result.length+" Bytes"
AC -Value $Outinfo -Path ".\log.csv"
#The conditions are met if the file is greater and engels 15 GB
If (($Result.length / 1073741824 ) -ge 15){$ProhibitLogonServers += $Computer}}}

#Mail message if no server are found                                                                                                                                                                            
If ($ProhibitLogonServers.length -eq 0){
$Mail = "Er is geen server gevonden die voldoet aan de voorwaarden om op ProhibitLogons te worden gezet" + "`n`n" + "Met Vriendelijke groet," +  "`n" + "Ochtend Controle Script"
Send-MailMessage -From "SendingAddress" -Subject "Prohibitlogons Report" -To "DestinationAddress" -Body $mail -SmtpServer $SMTP}

#Mail message one server is found
If ($ProhibitLogonServers.count -eq 1){
$Mail = "Er is een server gevonden die voldoet aan de voorwaarden om op ProhibitLogons te worden gezet. De server heeft als naam:" + "`n`n" + "$ProhibitlogonServers.Name" +"`n`n"+ "Met vriendelijke groet," + "`n`n" + "Ochtendcontrole Script"
Send-MailMessage -From "SendingAddress" -Subject "Prohibitlogons Report" -To "DestinationAddress" -Body $mail -SmtpServer $SMTP}

#Mail message if more than one server is found
If ($ProhibitLogonServers.count -gt 1){
$Mail = "Er zijn servers gevonden die voldoen aan de voorwaarden om op ProhibitLogons te worden gezet. De servers hebben de naam:" + "`n`n"
foreach ($server in $prohibitlogonservers){$Mail = $Mail + $Server.Name + "`r`n"}
$Mail = $Mail  + "`n" + "Met vriendelijke groet," + "`n`n" + "Ochtend Controle Script"
Send-MailMessage -From "SendingAddress" -Subject "Prohibitlogons Report" -To "DestinationAddress" -Body $mail -SmtpServer $SMTP}

#Opens array to check if the server has been set to prohibit logons. If servers are found a retry will be executed
$FailedServers = @()
If ($Prohibitlogonservers -ne $null){
Foreach ($Server in $Prohibitlogonservers){Set-XAServerLogOnMode -ServerName $Server.Name -LogOnMode Prohibitlogons -ComputerName CitrixServer}
Foreach ($Server in $Prohibitlogonservers){If ((Get-XAServer -ServerName $Server.Name -ComputerName CitrixServer).LogonMode -notmatch "ProhibitLogonOns"){$FailedServers += $Server}}}

#If a server is rebooting during the process you do want to make sure that server is set to Prohibit Logons. 
Start-sleep -s 900

#Retry setting the server to prohibit logons
If ($Failedservers.count -ne 0){
Foreach ($Server in $FailedServers){Set-XAServerLogOnMode -ServerName $Server.Name -LogOnMode Prohibitlogons -ComputerName CitrixServer}
$Failedservers = @()
Foreach ($Server in $FailedServers){If ((Get-XAServer -ServerName $Server.Name -ComputerName CitrixServer).LogonMode -notmatch "ProhibitLogonOns"){$FailedServers += $Server}}}

#Mail message if servers aren't set to prohibit logons
If ($Failedservers.count -ne 0){$Mail = "Er zijn servers niet succesvol op prohibitlogons gezet. Deze servers zijn:" + "`n`n"
foreach ($server in $Failedservers){$Mail = $Mail + $Server.Name + "`r`n"}
$Mail = $Mail  + "`n" +'Zet deze server(s) handmatig op ProhibitLogons' + "`n`n" + "Met vriendelijke groet," + "`n`n" + "Ochtend Controle Script"
Send-MailMessage -From "SendingAddress" -Subject "Prohibitlogons Failed" -To "DestinationAddress" -Body $mail -SmtpServer $SMTP}

 

Multiple levels GCI

In Powershell version 3 there is no way to limit the number of levels to do something in directories/registry/AD and so forth. So if you want to do that you can use a script like this:

[int]$Levels = "4"
$Directory = "\\Directory"
$List = GCI $Directory | Where {$_.psiscontainer -eq $true}
$Templist = $list
$temp = @()
While ($levels -ne 1){
Foreach ($item in $Templist){
$Temp += gci $item.Fullname | Where {$_.PSisContainer -eq $True}}
$list += $Temp
$Templist = $Temp
$Levels--
$Temp =@()}
$list = $list | Sort-Object Fullname
Foreach ($line in $List){Add-content -value $Line.Fullname -path ".\Export.csv"}

Export all TNSNames files from all servers in the domain.

A colleague asked me if it was possible to export all servers that have an Oracle directory. I made a script that collects all server from Active Directory. Next I test if the C:\Oracle Directory Exists. That is arrayed. Next I search the directories of tnsnames. Excluding the .sample files of course.

Import-Module ActiveDirectory
$ADComputers = Get-ADComputer -Filter * -Properties * | Where {$_.OperatingSystem -match "Server"}
$Computers =@()
ForEach ($ADComputer in $ADComputers){$ADComputer = $ADComputer.DNSHostName
If((Test-Path "\\$ADComputer\C$\Oracle") -eq $True){$Computers += $ADComputer}}

ForEach ($Computer in $Computers){$Folders =@( gci "\\$Computer\c$\Oracle\" -recurse)
ForEach ($Item in $Folders){if ($item -match "TNSNames.ora" -and $item.fullname -notmatch "sample"){Add-content -Value $item.fullname -Path ".\Export.csv"}}}

Search for specific text in files on a location

Sometimes a administrator is forced to do some cleaning up that should have been done a million years ago. When previous administrators have left you a nice bucket of history in your environment. A customer of mine used to have a few fileservers around that aren’t there anymore. In DNS those names are resolving to a new CIFS server. However that location is going to change again and now we are forced to clean up that old mess. Of course I’m not going to do the job of opening a few hundred thousand .ini, .config, .cfg and so forth myself. I created a script that does the job and can be delegated to someone else who has more time than me.

Clear
$Outputdir = \\Outputdirpath


$Location = Read-Host "Voer het volledige DFS pad in, in UNC Format bijvoorbeeld:\\DFSFolder"
$TestResult = Test-Path $Location
While ($Testresult -ne $true){
write-host "De opgegeven locatie bestaat niet. Voor opnieuw in" -b Black -f Red
$Location = Read-Host "Voer de DFS Locatie in in UNC Format bijvoorbeeld:\\DFSFolder"
$TestResult = Test-Path $Location}

$Extensions =@(Read-Host 'Voer een extensie in.De Extensie moet een . bevatten')
While ($Extensions -notmatch "."){$Extensions =@(Read-Host 'Voer een extensie in.De Extensie moet een . bevatten')}
$Choice = $null
While ($Choice -notmatch "[y|n]"){$Choice = read-host "Wilt u nog een Extensie toevoegen (Y/N)"
If ($Choice -match "Y"){While ($Extension -notmatch "."){$Extension =(Read-Host 'Voer een extensie in')}
$Extension += $Extension
$Choice = $Null}}

Remove-Variable Choice
$MatchList =@(Read-Host 'Voer een waarde in waaraan voldaan moet worden. Voor een drive mapping is een dubbele backslash vereist')
$Choice = $null
While ($Choice -notmatch "[y|n]"){$Choice = read-host "Wilt u waarde opgeven (Y/N)"
If ($Choice -match "Y"){$MatchItem =(Read-Host 'Voer een waarde in waaraan voldaan moet worden. Voor een drive mapping is een dubbele backslash vereist')
$MatchList += $MatchItem
$Choice = $null}}

$PathName = GI $Location
If ($PathName.Parent.Name -eq $Null){$ExportFile = "$OutputDir\ContentExport-"+ $PathName.Name + ".csv"}
If ($PathName.Parent.Name -ne $Null){$ExportFile = "$OutputDir\ContentExport-"+ $PathName.Parent.Name +"-"+ $PathName.Name +".csv"}

$List = gci $Location -Recurse | Where {$Extensions -match $_.Extension}
Foreach ($Item in $List){$Content = Get-Content $Item.fullname
$Pad = $item.fullname
Foreach ($Extension in $Extensions){If ($Content -match $Extension){Add-Content -Value  "Er is een verwijzing naar $Extension gevonden in: $Pad" -Path $Exportfile}}}

For those who do not speak Dutch very well. If you are searching for a drive mapping you should enter a double slash. The rest you’ll have to find out yourself 😉

Find old share names in files on Apps share

A client was talking about how he couldn’t quit sharing a certain share in his Citrix environment. There were to many connections still to that share. So I suggested that I could help him by making a script that looks for certain values in .ini, .log, .cmd, .bat, .cfg, .config etc files. You can adjust this to your own preference.

I did a check of the drive mapping G:\. Please note that a lot of log files contain Logging: which matches G:. That is why I did a match on G:\. In Powershell the ‘\’ character  is an expression followed by a special character which in this case will be \. That is why you need a double slash.

$Locatie = "\\ShareName" 
$Exportfile = ".\Exportfile.csv"
$List = gci $Locatie -Recurse | Where {$_.Extension -match ".ini" -or $_.Extension -match ".cfg" -or $_.Extension -match ".config" -or $_.Extension -match ".inc" -or $_.Extension -match ".bat" -or $_.Extension -match ".cmd" -or $_.Extension -match ".log" -or $_.Extension -match ".txt"}
Foreach ($item in $list){$Content = Get-Content $item.fullname
$Pad = $item.fullname
If ($Content -match "G:\\"){Add-Content -Value  "Er is een verwijzing naar G:\ gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "G:/"){Add-Content -Value  "Er is een verwijzing naar G:/ gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "ServerName1"){Add-Content -Value  "Er is een verwijzing naar ServerName1 gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "ServerName2"){Add-Content -Value  "Er is een verwijzing naar ServerName2 gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "ServerName3"){Add-Content -Value  "Er is een verwijzing naar ServerName3 gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "ServerName4"){Add-Content -Value  "Er is een verwijzing naar ServerName4 gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "ServerName5"){Add-Content -Value  "Er is een verwijzing naar ServerName5 gevonden in: $Pad" -Path $Exportfile}
If ($Content -match "ServerName6"){Add-Content -Value  "Er is een verwijzing naar ServerName6 gevonden in: $Pad" -Path $Exportfile}}

Get file size of old files on a fileserver

So I was at a costumer. They wanted an export of the file size that files older than 7 years populate on the file server. I made a very simple script that does the job.

$Locatie = "D:\"
#Verander het cijfer om het aantal jaar aan te passen
$Datum = (Get-Date).AddYears(-7)
$Outfile = ".\Output.txt"
$List = @(GCI $Locatie -Recurse | Where {$_.LastWriteTime -lt $Datum})
$Outinfo = "De lijst bevat "+ $list.count +" bestanden"
Add-Content -Path $Outfile -Value $Outinfo
$Bytes = 0
ForEach ($Item in $List){($Bytes=$Bytes + [int]$Item.length)}
$Outinfo = "De Bestanden bevatten $Bytes bytes"
Add-Content -Path $Outfile -Value $Outinfo
$Outinfo = "Dat is "+ $Bytes/1048576 +" MegaBytes"
Add-Content -Path $Outfile -Value $Outinfo

Renaming files and moving it to a different location

An OCE printer can only scan files to a FTP location with one name. There are no unique attributes that the Multifuctional printer can add to a file. This results in files being overwritten if not renamed immediately after being transferred. I’ve written a little script that is run every 5 seconds via Task Scheduler. This script renames files in a  unique format and then moves the file to some place else.

$Folder = "C:\Inetpub\FTProot\"
$Destination = "\\Ergensopdebozewereld"
$Applytime = (Get-Date).AddSeconds(-20)
$Content = @(gci $Folder | where {$_.LastWriteTime -lt $Applytime -and $_.PSIsContainer -eq $False})
Foreach ($item in $Content){$TEMP = $Item.LastWriteTime
$Time = Get-Date $TEMP -Format yyyyMMdd_HHmmss
$Name = $item.name.replace(".tif","")
Rename-Item -Path $Item.fullname -NewName "$Name_$Time.tif"
$Item = GI "$Folder\$Name_$Time.tif"
Move-Item -Path $Item -Destination $Destination -Force}

Replace text in local TNSNames.ora with Powershell

An administrator came to me today. Recently they had migrated from Oracle 10 to Oracle 11 and from HP UX to ODA (Oracle Database Appliance). Due to the fact that in this organization there are over 2000 databases, some applications wheren’t tested. In some cases application server look at the wrong TNSNames.ora. The request was to replace the text after host for the approriate host. I had the ‘luck’ that this request only included servers.

I created a that resolve his problem. The script contacts the ActiveDirectory for the list of “servers”. Then the script test if that server has an Oracle directory under C:\. Change this if you have Oracle installed under a different folder. Next there’s a check under the Oracle Directory for any folder that match Ora. These folders are included in an array. The next thing that will be checked is, if the TNSNames.ora exists in the usual folder. If that is the case the script continues. If it doesn’t exist the script will continue with the next folder or server.

Then the content of the TNSNames.ora will be loaded into the memory. The script renames the original TNSNames.ora to TNSNames.old. Or if that file is already in use in some other extension. Then all lines in the TNSNames will be check on the existance of few specific words and those words will be replaced with something else. At last the array NewTNSNames will be written to the location.

 

Import-Module ActiveDirectory
$ADComputers = Get-ADComputer -Filter * -Properties * | Where {$_.OperatingSystem -match "Server"}
$Computers =@()
ForEach ($ADComputer in $ADComputers){$ADComputer = $ADComputer.DNSHostName
If((Test-Path "\\$ADComputer\C$\Oracle") -eq $True){$Computers += $ADComputer}}
ForEach ($Computer in $Computers){$Folders =@( gci "\\$Computer\c$\Oracle\Ora*")
ForEach ($Folder in $Folders){If ((Test-Path "$Folder\Network\Admin\TNSNames.ora") -eq $True){$TNSNames = get-content "$Folder\Network\Admin\TNSNames.ora"
If ((Test-Path "$Folder\Network\Admin\TNSNames.old") -eq $False){Rename-item -Path "$Folder\Network\Admin\TNSNames.ora" -NewName "$Folder\Network\Admin\TNSNames.old"}
If ((Test-Path "$Folder\Network\Admin\TNSNames.NaChangeAugustus2014") -eq $False){Rename-item -Path "$Folder\Network\Admin\TNSNames.ora" -NewName "$Folder\Network\Admin\TNSNames.NaChangeAugustus2014"}
$NewTNSNames =@()
ForEach ($Item in $TNSNames){
If ($Item -match "odatst101a"){$NewTNSNames += $Item.replace("odatst101a","RobIsDeBarbecueKoning.local")}
If ($Item -match "odatst101b"){$NewTNSNames += $Item.replace("odatst101b","RobIsDeBarbecueKeizer.local")}
If ($Item -notmatch "odatst101a" -and $Item -notmatch "odatst101b"){$NewTNSNames +=  $Item}}
ForEach ($Item in $NewTNSNames){Add-Content -Value $Item -Path "$Folder\Network\Admin\TNSNames.ora" }}}}