Jere's Techblog

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.

Continue reading...

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
}

Continue reading...

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
}
Continue reading...

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
Continue reading...

Troubleshooting an App-V issue on a PVS image

This blog entry is based on the following, a little bit outdated article:

The problem is unfortunately still current it just brings some changes with Microsoft Server 2016. Therefore I took the liberty to copy some explanations from the “old article”.

Problem Description

During a recent application implementation project, we ran into the following issue. Some App-V applications, which were installed locally in the PVS image, were unable to start or they were throwing various error messages. One of the applications which were showing errors, was MS Office (Word, Excel, Powerpoint) viewer. The error thrown at startup of the application was the following: “The operating system is not presently configured to run this application.”

The App-V client was 5.0 SP2, but App-V 5.0 SP3 was also used as a troubleshooting step. The PVS target devices were configured as such:
Streamed disk
Persistent disk (flush overflow)
Re-installing the application in the image, solved the issue for that particular application. However, we wanted to know the root cause of this issue, so we logged a case at Citrix. This was done because the behavior was not existing on a regular non-streamed VM.
After extensive troubleshooting together with Citrix support we discovered the root cause:
One of the registry keys (HKLM\SOFTWARE\Microsoft\AppV\MAV\Configuration\Packages\<package ID>) containing the PackageRoot value contained a faulty HarddiskVolume number.
This volume was indicated as 3, whereas the streamed disk volume number was 2.

Solution

Correcting HarddiskVolume3 into HarddiskVolume2 did solve the issue.
The reason why the HarddiskVolume3 value got into the registry was because these applications where installed in the image on the template machine. This was the machine from which the initial vdisk was captured. During the installation of the particular App-V applications, the original disk was still attached .


This is issue is definitely not Citrix or PVS related, but can be encountered on such a setup.
To prevent this issue from happening again in the future, the original disk was detached from the template VM.

You can get the disknumber in CMD with “DISKPART -> ListDisk” or PowerShell “Get-Disk”.

My expirience and solution with this issue on Server 2016:

In our Environment we ran into the same problem and we could fix this on Server 2008R2 & Citrix 6.5, PVS 7.15 with the modification of one of the registry keys (with a Startupscript during worker boot). (HKLM\SOFTWARE\Microsoft\AppV\MAV\Configuration\Packages\<package ID>) containing the PackageRoot value contained a faulty HarddiskVolume number.

On Server 2016 (Citrix 7.17) everything was useless. Creating or deleting a disk on the masterimage or changing the RegKey didn’t work. I also didn’t find a way to change the disk volume number.

The problem could only be solved by adjusting the call parameter of the application. If the application is started in the App-V context it works fine.

As an example:

Microsoft InfoPath 2013

C:\ProgramData\Microsoft\AppV\Client\Integration\D24C3BDD-8FAD-44D3-998C-933F8F053682\Root\Office15\INFOPATH.EXE /appvve:d24c3bdd-8fad-44d3-998c-933f8f053682_6b0281c5-bb0b-49fb-b52c-a6651e8ed2ed

filetype associations fix

to fix the filetype associations you need to add the “/appvee:**APPV-ID***” parameter to the registry root class:

HKEY_CLASSES_ROOT\InfoPath.Solution.4\shell\Open\command

“C:\ProgramData\Microsoft\AppV\Client\Integration\D24C3BDD-8FAD-44D3-998C-933F8F053682\Root\Office15\INFOPATH.EXE” /appvve:d24c3bdd-8fad-44d3-998c-933f8f053682_6b0281c5-bb0b-49fb-b52c-a6651e8ed2ed “%1”

Continue reading...

Query big ADObject / Containers

The Powershell AD-Modules have certain restrictions when it comes to querying large objects, this can be bypassed by ADSI Query.

Here an example how to read them and how to iterate on users of a group:

#by J.Kühnis 13.03.2019
#example ADSI Query Powershell
$BigGroup = "someADGroupName"
$ADGroup1 = "someADGroup1"
$ADGroup2 = "someADGroup2"


$groupname = $BigGroup
$groupdsn = (Get-ADGroup $groupname).DistinguishedName
$group =[adsi]”LDAP://$groupdsn” 
$groupmemebrs = $group.psbase.invoke("Members") | % {$_.GetType().InvokeMember("SamAccountName",'GetProperty',$null,$_,$null)}

$groupmemebrs | foreach {
    
    $usradgroups = GET-ADUser -Identity $_ –Properties MemberOf | Select-Object -ExpandProperty MemberOf | Get-ADGroup -Properties name | Select-Object name
    IF ($usradgroups.name -notContains $ADGroup1 -and $usradgroups.name -notContains $ADGroup2) {

        #User is not a Member of ADGroup1 & ADGroup2

        }
        Else{
          #User is MemberOf ADGroup1 & ADGroup2
        }
}

Here also an example using a Class to just specify the object the way you like:

#by J.Kühnis 09.10.2019
#Set variables
$ADGROUP = "someAdGrp"

# Load AD-Module
IF (!(Get-Module -Name ActiveDirectory)) {
    Import-Module -Name ActiveDirectory
    IF (!(Get-Module -Name ActiveDirectory)) {
    start-sleep 10
    Write-Warning "No AD-Module Found"

        Exit
    }
}
$groupname = $ADGROUP
$groupdsn = (Get-ADGroup $groupname).DistinguishedName
$group =[adsi]”LDAP://$groupdsn” 
$groupmemebrs = $group.psbase.invoke("Members") | % {$_.GetType().InvokeMember("SamAccountName",'GetProperty',$null,$_,$null)}

class User{
[string]$Name
[string]$SamAccountName
[string]$UserPrincipalName
[string]$Mail
[string]$extensionAttribute7
[string]$extensionAttribute9
}


$Userlist = @()
$groupmemebrs | ForEach-Object {
    $usrATTR = GET-ADUser -Identity $_ –Properties Name,SamAccountName,UserPrincipalName,mail,extensionAttribute9, extensionAttribute7
    
    $User = [User]::new()
    $User.Name = $usrATTR.Name
    $User.SamAccountName = $usrATTR.SamAccountName
    $User.UserPrincipalName = $usrATTR.UserPrincipalName
    $User.Mail = $usrATTR.Mail
    $User.extensionAttribute1 = $usrATTR.extensionAttribute1
    $User.extensionAttribute2 = $usrATTR.extensionAttribute2

    $Userlist += $User
}
$Userlist | format-table
Continue reading...

Copy-Items with folder Structure and Filter in a Foreach-Parallel Workflow

#J.Kühnis 08.03.2019
$Sourcefolder= "\\localhost\C$\Temp\1"
$Targetfolder= "C:\Temp2\1"


$query = Get-ChildItem $Sourcefolder -Recurse | Where-Object {$_.LastWriteTime -gt [datetime]::Now.AddDays(-1)}


workflow CopyJob {
    param (
    [Object[]]$query,
    [String]$Sourcefolder,
    [String]$Targetfolder
    )
    
Foreach($item in $query){
    $dest = $Targetfolder + $item.FullName.SubString($Sourcefolder.Length)
    
    #Write-Host $dest -ForegroundColor Yellow
    Copy-Item $item.FullName -Destination $dest -Force
}
}

CopyJob -query $query -Sourcefolder $Sourcefolder -Targetfolder $Targetfolder
Continue reading...