So I recently created a new ownCloud 10 server to get away from ownCloud 9. This meant creating a new CentOS 7 VM bladybladyblah…
One thing that caught me out, among many to do with ownCloud, was that the original user created during the setup process couldn’t save or view files after I had reconfigured the home directory to be more secure.
After looking in the MYSQL database, I saw that the original user’s home directory had not been updated to match the new path. To check this I used the following commands and looked for the home column:
USE owncloud;
SELECT * FROM oc_accounts;
After those commands, I updated the users home setting by using the following command:
UPDATE oc_accounts SET home="/new/dir/username" WHERE user_id="user";
Nice simple fix for an issue that was driving me up the wall.
New and improved LAPS WinForm because the original one, found here, was kind of crap. It didn’t handle exceptions very well and I don’t think the group policy update worked at all after some further debugging.
I am please to present the new GUI for LAPS:
The best place to download this from would be my TechNet gallery
Today, I finally got around to making a script that will run automatically on my network storage server (Raspberry Pi with a dinky USB hard drive) and check if the USB HDD is accessible.
This issue started a couple of weeks ago where I was getting weird IO errors on the USB disk about every 2 weeks. Instead of buying a new drive, creating a RAID array or anything else equally as intelligent and appropriate, I decided to just reboot my Raspberry Pi every time this happened. Now, I don’t want to do this manually every time so I finally created a script and added it to my cron jobs.
You can see the script I used below:
#!/bin/bash
if [ ! -d "path/to/check" ]; then
#Directory is not found and HDD is not okay, do whatever is below
uptime=$(uptime)
currenttime=$(date)
echo "Host rebooted at $currenttime. Uptime was$uptime" >> /path/to/output.txt
sudo reboot
fi
My crontab job is running as root because the sudo reboot part was giving me a couple of issues. This is the entry in the root crontab:
This is a little WinForm I created that would output the group membership for a domain user or FBA (Forms-Based Authentication) user on SharePoint.
This is what the form looks like, it gives the option for a domain or FBA user and also checked if the user exists before trying to get the relevant information:
The form first checks if CredSSP is configured on your machine to delegate your credentials to the SharePoint server. The form then loads, waits for your input, validates your input and finally collects the group information for your input.
And finally, this is the code for the Winform. I’ve removed some details as they need to be filled in by you. Enjoy!
#CHECKING CREDSSP SETTINGS
if ((Get-Item WSMan:\localhost\Client\Auth\CredSSP).value -eq $false){
#CREDSSP NOT CONFIGURED, EXITING
Write-Host @"
CredSSP is not configured!
Please open an elavated PowerShell prompt and run:
Enable-WSManCredSSP -Role client -DelegateComputer sandsharepointf
"@
Exit
}else{}
#LOADING ASSEMBLIES
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
#ICON FOR THE FORM
[string]$icon64=@"
#base64data
"@
#CONVERTING BASE 64 ICON INTO GRAPHIC
$iconstream = [System.IO.MemoryStream][System.Convert]::FromBase64String($icon64)
$iconbmp = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($iconstream)
$iconhandle = $iconbmp.GetHicon()
$icon = [System.Drawing.Icon]::FromHandle($iconhandle)
#FORM
$SharePoint_Membership_Form = New-Object system.Windows.Forms.Form
$SharePoint_Membership_Form.ClientSize = '400,278'
$SharePoint_Membership_Form.text = "SharePoint Membership"
$SharePoint_Membership_Form.TopMost = $false
$SharePoint_Membership_Form.StartPosition = "centerscreen"
$SharePoint_Membership_Form.Icon = $icon
$SharePoint_Membership_Form.FormBorderStyle = "Fixed3D"
#USERNAME LABEL
$Username_Label = New-Object system.Windows.Forms.Label
$Username_Label.text = "Enter a username:"
$Username_Label.AutoSize = $true
$Username_Label.width = 25
$Username_Label.height = 10
$Username_Label.location = New-Object System.Drawing.Point(146,12)
#USERNAME TEXTBOX
$Username_Textbox = New-Object system.Windows.Forms.TextBox
$Username_Textbox.multiline = $false
$Username_Textbox.width = 175
$Username_Textbox.height = 20
$Username_Textbox.location = New-Object System.Drawing.Point(115,33)
#VARIABLE FOR KEYDOWN
$Username_Textbox_keydown = {}
#KEYDOWN ASSIGNED
$Username_Textbox_keydown = [System.Windows.Forms.KeyEventHandler]{
if ($_.keycode -eq 'Enter'){
$Search_Button.PerformClick()
}
}
#REGISTER KEYDOWN HANDLER TO USERNAME TEXTBOX
$Username_Textbox.add_keydown($Username_Textbox_keydown)
#DOMAIN RADIO BUTTON
$Domain_User_RB = New-Object system.Windows.Forms.RadioButton
$Domain_User_RB.text = "Domain User"
$Domain_User_RB.AutoSize = $true
$Domain_User_RB.width = 104
$Domain_User_RB.height = 20
$Domain_User_RB.location = New-Object System.Drawing.Point(120,64)
$Domain_User_RB.Checked = $true
#SHAREPOINT FBA USER RADIO BUTTON
$FBA_User_RB = New-Object system.Windows.Forms.RadioButton
$FBA_User_RB.text = "FBA User"
$FBA_User_RB.AutoSize = $true
$FBA_User_RB.width = 104
$FBA_User_RB.height = 20
$FBA_User_RB.location = New-Object System.Drawing.Point(215,64)
#SEARCH BUTTON
$Search_Button = New-Object system.Windows.Forms.Button
$Search_Button.text = "Search"
$Search_Button.width = 60
$Search_Button.height = 30
$Search_Button.location = New-Object System.Drawing.Point(171,89)
#SEPERATOR LINE
$Seperator_Label = New-Object system.Windows.Forms.Label
$Seperator_Label.text = ""
$Seperator_Label.AutoSize = $false
$Seperator_Label.BorderStyle = "Fixed3D"
$Seperator_Label.width = 390
$Seperator_Label.height = 2
$Seperator_Label.location = New-Object System.Drawing.Point(5,124)
#OUTPUT TEXTBOX
$Output_Textbox = New-Object System.Windows.Forms.TextBox
$Output_Textbox.Multiline = $true
$Output_Textbox.Width = 390
$Output_Textbox.Height = 142
$Output_Textbox.Location = New-Object System.Drawing.Point(5,131)
$Output_Textbox.ReadOnly = $true
$Output_Textbox.ScrollBars = "vertical"
#ADDING CONTROLS TO FORM
$SharePoint_Membership_Form.controls.AddRange(@($Domain_User_RB,$FBA_User_RB,$Seperator_Label,$Username_Label,$Username_Textbox,$Search_Button,$Output_Textbox))
$Search_Button.add_click({
$Output_Textbox.Text = ""
#DATE FOR OUTPUT
$date = Get-Date
$username_value = $Username_Textbox.Text
$Username_Prefix = $null
$location = #base location
#SETTING SEARCH VALUES BACK TO FALSE
$Search_On_AD_User = $false
$Search_On_FBA_User = $false
#CHECKING IF USERNAME TEXTBOX IS EMPTY
if ($Username_Textbox.Text.Length -le 0){
#IF EMPTY, VARIABLE IS FALSE
$Output_Textbox.AppendText("$date - $Username cannot be empty! `n")
$Username_Not_Empty = $false
}else{
$Username_Not_Empty = $true
$Output_Textbox.Text = ""
}
#RUNS IF DOMAIN USER RADIO BUTTON IS CHECKED
if ($Domain_User_RB.Checked -and $Username_Not_Empty){
try{
$Output_Textbox.AppendText("$date - Searching for $username_value `n")
Get-ADUser -Identity $username_value
$Output_Textbox.AppendText("$date - Found user! `n")
$Search_On_AD_User = $true
$Search_On_FBA_User = $false
$Username_Found = $true
}catch{
$Output_Textbox.AppendText("$date - Cannot find domain user `n")
$Username_Found = $false
}
}
#RUNS IF FBA USER RADIO BUTTON IS CHECKED
if ($FBA_User_RB.Checked -and $Username_Not_Empty){
$SPAdmin = "sharepoint_admin_user"
$credential = New-Object System.Management.Automation.PSCredential $SPAdmin, (Get-Content "$location\sharepoint_admin_user_encrypted_password.txt" | ConvertTo-SecureString )
$sb = {
$username = $args[0]
Add-PSSnapin microsoft.sharepoint.PowerShell
$user = Get-SPUser -Limit All -Web http://SHAREPOINTSERVER |
Where-Object {$_.loginname -like "i:0#.f|fbamembershipprovider|$username"}
return $user
}
$Output_Textbox.AppendText("$date - Trying to find $username_value... `n")
$invokeoutputfbasearch = Invoke-Command -ScriptBlock $sb -ComputerName SHAREPOINTSERVER -Authentication Credssp -Credential $credential -ArgumentList $username_value
if ($invokeoutputfbasearch){
#FOUND USER
$Username_Found = $true
$Search_On_FBA_User = $true
$Search_On_AD_User = $false
$Output_Textbox.AppendText("$date - Found FBA user!`n")
}else{
#NOT FOUND USER
$Username_Found = $false
$Output_Textbox.AppendText("$date - Cannot find FBA user `n")
}
}
#ONLY RUNS IF BELOW CONDITIONS ARE MET
if ($Username_Found -and $Username_Not_Empty){
#ASSIGNING THE RIGHT USERNAME FORMAT
if ($Search_On_AD_User){
$Username_Prefix = "*|DOMAIN_NAME\"
}else{
$Username_Prefix = "i:0#.f|fbamembershipprovider|"
}
$SPAdmin = "sharepoint_admin_user"
$credential = New-Object System.Management.Automation.PSCredential $SPAdmin, (Get-Content "$location\sharepoint_admin_user_encrypted_password.txt" | ConvertTo-SecureString )
$sb = {
$groups = $null
$prefix = $args[0]
$username = $args[1]
Add-PSSnapin Microsoft.SharePoint.PowerShell
$user = get-SPUser -limit all -web http://SHAREPOINTSERVER |
Where-Object { $_.loginname -like "$prefix$username" }
$SPGroups = get-spsite -limit all |
Select-Object -ExpandProperty rootweb |
Select-Object -ExpandProperty siteusers |
Where-Object { $user.userlogin -eq $_.loginname } |
Select-Object -ExpandProperty groups |
Select-Object -ExpandProperty name
foreach ($i in $SPGroups){
$groups = $groups + " - $i `r`n"
}
return $groups
}
$Output_Textbox.AppendText("$date - Collecting group info on $username_value... `n")
$InvokeOutputfinal = Invoke-Command -ScriptBlock $sb -ComputerName SHAREPOINTSERVER -Authentication Credssp -Credential $credential -ArgumentList $Username_Prefix,$username_value
$Output_Textbox.AppendText("`n")
$Output_Textbox.AppendText("$InvokeOutputfinal")
}else{#THIS SERVES ONLY AS A TRAP TO STOP ANYTHING RUNNING
}
})
#DISPLAYING FORM
[void]$SharePoint_Membership_Form.ShowDialog()
This is a nice little trick I learnt whilst automating domain user creation with PowerShell, I found generating passwords in PowerShell was always ugly. Just see the example below from a previous post I’d made:
This would generate a password like “cDUtxlvM5” which is just about as ugly as the code used to create it.
So I decided to use DinoPass instead since it created better looking passwords without the faff of generating them in PowerShell. This is a the code I used:
Which would give me a much nicer, but still secure, password like “poorJump62”. Then to use it when automating domain user creation, I would use the below and put the whole thing into a variable that I would set the password to:
I have created the *final* iteration of this WPF form which can be found here
*UPDATE*
I didn’t like having to remote desktop into my domain controller and couldn’t figure out if there was a LAPS tool included in RSAT tools so I decided just to make my own and to add some extra features.
I wanted the GUI to look pretty much identity to the actual LAPS GUI. You can see the difference below:
My custom GUI
Default GUI
You might be able to see that I changed the “Set” button to say “Set and Update”. This was because I wanted the form to also attempt to update the group policy settings on the computer so that it would get a new password a lot quicker than the original GUI.
There’s not much else I can say, I will leave the entire script below for you to copy and paste. You will need to add the domain controller for your environment in the $domaincontroller variable at the top of the script. I have converted this to an EXE and run whenever I need it, never skips a beat. Let me know how you get on with it. Enjoy!
Bit of a weird post today, I had a need to update the SSL certificate for an old DRAC (Dell Remote Access Controller) 5 module. This is just an overview of what I did.
First I logged into the DRAC and went to System > Remote Access > Configuration > SSL > Generate a new certificate signing request (CSR). In here I entered my details and put the address I would use for connecting to the server as the common name.
After I clicked “Submit”, I got a small txt file called “csr.txt”. I then needed to get this signed by a Certificate Authority (CA) so that I could get an actual certificate file. Note that the format you want for DRAC 5 is .cer
The CA I used for this was “getacert“, they’re a bit “ghetto” with their site not even using the technology that they provide… kind of ironic but I was desperate.
On this site I entered the contents of my csr.txt file and clicked “Submit CSR“. This them gave me the certificate file, signed by getacert.
Finally, I went back into the DRAC management webpage (in the same location as pointed out earlier) and selected the option to “Upload Server Certificate” Now just select the .cer file you got from the CA and click submit. This will cause the management site to go down for a couple of minutes whilst it configures the new certificate.
This is a weird issue I encountered where even though I had tried restarting explore.exe and disabled and enabled desktop icons, they still weren’t showing. Even weirder was the fact that only some of them were showing whilst others weren’t. Weird indeed.
Here you can see that the text file “Test” isn’t showing on my desktop even though it is in the desktop folder:
To remedy this issue, what I had to do was right click on the desktop, go into “Sort By” and select “Name“. This jiggled the desktop and made the text file appear. Not sure what causes this at all.
Hopefully someone finds this useful, I know I could have done with this information at the time. Enjoy!
From my previous post, found here, you can see that I have formatted the text to be a specific colour depending on what sort of output I get. So for errors I make the text red and for successful messages I make the text green.
This is easy to implement into BASH scripts and a lot of other formatting can be applied as well. In this post, I will be covering the colorization (probably not a word), underlining, bold text and resetting the changes.
Colour Possibilities:
0 – Black
1 – Red
2 – Green
3 – Yellow
4 – Blue
5 – Magenta
6 – Cyan
7 – White
$(tput setaf 1)TEXT HERE
Bold Text:
#Starts bold characters
$(tput bold)TEXT HERE
#Ends bold characters
$(tput sgr0)TEXT HERE
I would just like to add here that tput sgr0 removes allformatting and returns text to the default style and colour.
Underlining:
#Starts underlining
$(tput smul)TEXT HERE
#Ends underlining
$(tput rmul)TEXT HERE
Below is a full script which includes all the possible combinations of the examples above, apart from black text.
In this post, I’ll discuss how I created a PowerShell script that runs when a user logs out of a terminal server and cleans up a directory in their home folder that was filling up with space due to application crashes.
This code will get the users profile root path and then check if the application folder exists, if it doesn’t then the script ends. If it does exist, the script will cycle through each entry and remove it.
The -Confirm:$FALSE parameter was added because the script kept asking for confirmation when deleting each item. This stops this behaviors and deletes each item without a confirmation prompt.
Now that I have the script and it is working as expected, I create a local group policy that will use:
Name – “powershell.exe”
Parameters – “-F “C:\path\to\file.ps1”
You can see this in the screenshot below:
This group policy was added under:
User Configuration – Windows Settings – Scripts (Logon/Logoff) – Logoff
Hopefully you can replicate what I have done and don’t experience any issue. Note that you might need to change the script execution policy on the machine before this works properly. Just something to keep in mind if the group policy isn’t working. Enjoy!