Jere's Techblog

Blog CONTENTS

We are drowning in information, but starved for knowledge. - John Naisbitt

Cloud

This area is all about private cloud, SaaS,IaaS,PaaS but also about solutions like Nextcloud,OwnCloud,Seacloud,OneDrive

Linux

If you want to know more about the OpenSource Penguin, you've come to the right place. Learn more about what you can do with the OS from the 90s

Network

Network professional? I'm sure I'm not, but I'm sure you'll find some hints about useful tools. Or maybe you just want to use a SSH service as proxy, tunnel.

Scripting & Programming

A large part of this blog area is about Powershell, but in the future there will be more content like SQL,C#,VBS,.Net etc. as well.

Web

HTML5, CMS, CSS and respsonsive are all unfamiliar terms? Then this is the right place for you, I am not a webprofessional, but I can give some start tips to the newbies.

Windows

With over 80% market share, Windows is the world's leading operating system. Tips & tricks, tutorials, troubleshooting and much more can be found in this section.

Citrix

It's all about Terminal Services, NetScaler, VDI, XenApp, XenDesktop, StoreFront, CitrixDirector and Citrix Delivery Controller.

Hypervisor

Hypervisors, where our virtual machines are hosted. Installation Guides, Comparisons, Configurations and more..

news

Nextcloud App recommendations

Personally I am a huge fan of NextCloud currently I run 4 environments with over total over 100 users.
Already in the beginnings of OwnCloud I have been working with it and I switched relatively quickly to the fork “NextCloud”. It seems to me that a lot has happened since the fork, the community has grown much bigger. Another advantage is that you have your own DataShareing solution without using commercial products.

I would like to present you my Top 5 solutions, which I use on every NextCloud environment.

Group folders

Calendar

User usage report

File access control

Quota warning

By

Read More

Example WPF Datagrid with Combobox (Powershell Binding)

With WPF GUI elements, it can happen that you like to connect two detached elements with each other. A classic example are comboboxes within tables. You want to read the value of the combobox with the corresponding row. For this the binding of elements is necessary. Enclosed a small example, how you can accomplish this:

https://github.com/jkuehnis/PowerShell-DataGrid-with-Combobox

By

Read More

local & remote msu patchfile installation with Powershell / Windows Update Standalone Installer

Windows Update Standalone Installer

The patch installation is done via wusa.exe.

The following print screen shows the parameters of the Windows Update Standalone Installer.

local installation

As far as I know, the patch cannot be installed with native powershell, means we have to address the wusa.exe in powershell. Of course Powershell is a nice way to automate the whole process.

In the following example, the patch is copied from a UNC share and installed locally.

$patchname = "kb13245.msu"

$patchsource = "\\some\unc\path\kb13245.msu"

Copy-Item $patchsource -Destination "$env:SystemDrive\Temp" -Force

wusa.exe "$env:SystemDrive\Temp\$patchname" /quiet

remote installation

I was not able to run wusa.exe remotely, any tests with workflows, Remotepowershell (Invoke-Command CMDLeet) failed. Even triggering a localy copied batch file caused problems. The wusa.exe process was executed with the correct parameters but aborted after a few seconds.
Even with an Invoke-Command and the parameter -Wait it didn’t work.

Probably it’s because you intervene in the system and perform an unauthorized action.

With the PSExec.exe it is possible to start the process remotely.

The principle is very simple, you have to copy the patch to the appropriate target computer. Then PSExec starts a remote process on the target computer and executes the wusa.exe with the corresponding parameters. The wusae.exe must point to the path where the patch was copied.

#16.05.2019 by JKU
$Hotfix = 'kb-12345.msu'
$HostName = 'F.Q.D.N'
$DestinationPath = "\\$Hostname\c$\Temp\"

Copy-Item C:\temp\$Hotfix -Destination $DestinationPath
#Start Process with PSExec.exe
& C:\Temp\PsExec.exe -accepteula -s  \\$HostName wusa C:\Temp\$Hotfix /quiet /norestart

And so you can distribute a patch for multiple computers with a simple iteration.

full remote automation

There are of course several ready-made scripts to install multiple patches on multiple computers. The script which I use in the company environment, I have inserted below. The code does not come from me, but from the following forum post: https://community.spiceworks.com/topic/2054098-silently-install-patches-remotely-and-reboot?page=1#entry-7246666

#by https://community.spiceworks.com/topic/2054098-silently-install-patches-remotely-and-reboot?page=1#entry-7246666

$RootHotfixPath = 'Patches\'
 
$Hotfixes = @('KB3125574_x64.msu')
$Servers = Get-Content 'MachineList.txt'

foreach ($Server in $Servers)
{
    Write-Host "Processing $Server..."

    $needsReboot = $False
    $remotePath = "\\$Server\c$\Temp\Patches\"
    
        if( ! (Test-Connection $Server -Count 1 -Quiet)) 
    {
        Write-Warning "$Server is not accessible"
        continue
    }

        if(!(Test-Path $remotePath))
    {
        New-Item -ItemType Directory -Force -Path $remotePath | Out-Null
    }
    
    foreach ($Hotfix in $Hotfixes)
    {
        Write-Host "`thotfix: $Hotfix"
        $HotfixPath = "$RootHotfixPath$Hotfix"

        Copy-Item $Hotfixpath $remotePath
        # Run command as SYSTEM via PsExec (-s switch)
        & C:\Windows\PsExec -s \\$Server wusa C:\Temp\Patches\$Hotfix /quiet /norestart
        write-host "& C:\Windows\PsExec -s \\$Server wusa C:\Temp\Patches\$Hotfix /quiet /norestart"
        if ($LastExitCode -eq 3010) {
            $needsReboot = $true
        }
    }

    # Delete local copy of update packages
    Remove-Item $remotePath -Force -Recurse

    if($needsReboot)
    {
        Write-Host "Restarting $Server..."
        Restart-Computer -ComputerName $Server -Force -Confirm
    }
}

Map Share to free Driveletter

With this code snippet a share can be mapped to the next free drive letter.

$share = "\\any\unc\path"
$PSProviderAlphabet = [char[]]([char]'C'..[char]'Z')
$UsedPSProvider = (get-psdrive).Name | Sort-Object
$FreePSProvider = $PSProviderAlphabet | ? {$UsedPSProvider -notcontains $_}

New-PSDrive -Name $FreePSProvider[0] -PSProvider "FileSystem" -Root $share

It is especially useful if you have to work with a driveletter in the code or if the share has to be mapped in the Scirpt and has to be removed at the end of the script.

Add License to all O365 Users trough Powershell

First of all you need to install the Powershell Module and Connect to the MSOnline Serivce

Install-Module MSOnline
Import-Module *
Connect-MsolService -Credential (get-credential)

You can get an overview of all Users trough this Command:

Get-MsolUser

This script block can be used to assign a license to any user who is not a licensed user.

This example assumes that the command “(Get-MsolAccountSku).accountskuid” retrive only one value/license. If you have several licenses you have to specify this for the variable “$SKUID“.

#byJKU 29.04.2019 
#Activate each user with MSolAccountSKU License
$SKUID= (Get-MsolAccountSku).accountskuid

IF ((Get-MsolUser -UnlicensedUsersOnly).UserPrincipalName){
    (Get-MsolUser -UnlicensedUsersOnly).UserPrincipalName | % {
    Set-MsolUserLicense -UserPrincipalName $_ -AddLicenses $SKUID
    }
}Else{
    Write-host "There is no User without License" -ForegroundColor Yellow
}

Install Eclipse Plugins from command line

tested with:

Eclipse Java EE IDE for Web Developers – Version: Oxygen.1a Release (4.7.1a)

Eclipse Java EE IDE for Web Developers – Version: 2019-03 (4.11.0)

Basics

There is a nice detailed blog article which describes how to install the Eclipse plugins.
The description is for Linux, it works exactly the same on Windows.
The syntax is shown with an example and it is explained how to get to the repository information.

Here is an example for the Windows Commandline:

C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe -application org.eclipse.equinox.p2.director -repository http://download.eclipse.org/releases/oxygen -installIU org.eclipse.jgit.http.apache.feature.group

However, there are some problems with automation:

  • The plugins cannot be installed in parallel mode, at least this didn’t work for me.
  • Prerequisits will not be automaticly installed.

The automated solution:

First you have to manually try out the commands to get the order and dependencies/prerequsits right.

The loop in the script will sequentially process the installations…if a plugin installation takes more than 5min the Eclipse process will stop and the next plugin will be installed.

Don’t forget ro Run Powershell in elevated mode.

#09.04.2019 by J.Kühnis installation Eclipse Plugins

#Install Eclipse Addons from Web-repository
[array]$InstallArguments = @(
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.it.ide.adapter.sdk.feature.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository http://download.eclipse.org/releases/oxygen -installIU org.eclipse.jgit.http.apache.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.it.commons.command.http.apacheclient'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.it.op.cockpit.ui.feature.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.core.tools.eclipse.help.feature.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository http://download.eclipse.org/releases/oxygen -installIU org.eclipse.libra.facet'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository http://download.eclipse.org/releases/oxygen -installIU org.eclipse.libra.facet.feature.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository http://download.eclipse.org/releases/oxygen -installIU org.eclipse.jpt.jpadiagrameditor.feature.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.core.tools.eclipse.server.feature.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.jvm.profiling.feature.group'
'&"C:\Program Files\eclipse\jee-latest-released\eclipse\eclipse.exe" -application org.eclipse.equinox.p2.director -repository https://tools.hana.ondemand.com/oxygen/ -installIU com.sap.idm.dev-ui-feature.feature.group'
)
                                                                                                             
Foreach($argument in $InstallArguments){
    #Install Addins
    Write-Host $argument -ForegroundColor Yellow
    $argument | Invoke-Expression
    Start-Sleep 5

    #Check if Service is Running and wait | Exit after 300Seconds
    [int]$counter = 0
        
        Do {  
            $ProcessesFound = get-process -Name *eclipse*
            If (($ProcessesFound) -and ($counter -le "30")) {
                Start-Sleep 10
                $counter++
                Write-Host "Still running: $($ProcessesFound)  $counter"
            }Else{
                IF ($counter -gt "30"){
                    Write-Host "Try to kill running Process while Process is taking more than 5 Minutes" -ForegroundColor DarkYellow -BackgroundColor Black
                }Else{
                    Write-Host "Process ended by installer" -ForegroundColor Green
                }
                Get-Process *eclipse* | Stop-Process -Force
            }
        } Until (!$ProcessesFound)

        Clear-Variable -Name counter -Scope Global
        Start-Sleep 2
}

Citrix DeliveryController DB rejoin; The operation could not be performed because of a configuration logging error.

To rejoin a Citrix Broker into a existing or migrated Databese, there are a lot of usefull articles:

https://support.citrix.com/article/CTX212941

https://support.citrix.com/article/CTX216504

Problem Cause

In some cases you can’t configure the Monitor and Log DataStore Connections after you deleted the Connection with:

Set-MonitorDBConnection -DataStore Monitor -DBConnection $null -force
Set-MonitorDBConnection -DBConnection $null -force
Set-LogDBConnection -DataStore Logging -DBConnection $null -force
Set-LogDBConnection -DBConnection $null -force

If you like to rejoin the Connection with the following command:

Set-LogDBConnection -DataStore Logging -DBConnection $csLogging

You get the following error:

Set-LogDBConnection : The operation could not be performed because of a configuration logging error.
At line:1 char:1


Set-LogDBConnection -DataStore Logging -DBConnection $csLogging
~~~~~~~~~~~~~~~CategoryInfo : InvalidOperation: (:) [Set-LogDBConnection], InvalidOperationException
FullyQualifiedErrorId : Citrix.XDPowerShell.Status.ConfigurationLoggingError,Citrix.ConfigurationLogging.Sdk.DataStore.Commands.SetLogDBConnectionCommand

Solution 1

There is a possibility to disable the settings before nullify the connections:

Set-LogSite -State "Disabled"
Set-MonitorConfiguration -DataCollectionEnabled $False

then go ahead with this article https://support.citrix.com/article/CTX216504 and reenable the Settings; run those commands as last step:

Set-LogSite -State "Enabled"
Set-MonitorConfiguration -DataCollectionEnabled $true

Solution 2

Just use the “-force” parameter while setting up the DB Connection. Afterwards i recommend to reboot the Broker Server.

Set-LogDBConnection -DataStore Logging -DBConnection $csLogging -force
Set-MonitorDBConnection -DataStore Monitor -DBConnection $csMonitoring -force