Erreur Conversion : SetOwner en type System.Security.Principal.IdentityRefer

Welcome Forums General PowerShell Q&A Erreur Conversion : SetOwner en type System.Security.Principal.IdentityRefer

Viewing 1 reply thread
  • Author
    Posts
    • #200114
      Participant
      Topics: 1
      Replies: 0
      Points: -9
      Rank: Member

      Hello, i’m new to rhis forum and also noob in powershell.

      I’m testing this script ( automated installation postgresql in windows)

      It supposed to work in Windows7.

      I’m testin it in Windows 10.

      Postgresql is well installed , but the script stopped before the end with this error :

       

      Install-Postgres : Impossible de convertir l’argument «identity» (valeur «post24») de «SetOwner» en type «
      System.Security.Principal.IdentityReference»: «Impossible de convertir la valeur «post24» du type «System.String» en type «
      System.Security.Principal.IdentityReference».»
      Au caractère Ligne:1 : 32
      + … e Install-Postgres;Install-Postgres -User “post24” -Password “change”
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
      + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Install-Postgres

      I don’t know if this is due to a syntax error ( Powershell has changed in windows 10 ? )

      • Postgresql is well installed ans seems to work, i would like to understand the impact of the mistake  . Should i have desactive exception so that the script can pursuit ?
      • Any idea/advice will be appreciated.

      Here’s the script :

      
      Function Install-Postgres
      {
      <#
      
      .SYNOPSIS
      PostgreSQL unattended install
      
      .DESCRIPTION
      PostgreSQL unattended install script does the following:
      creates a local windows user that PostgreSQL will use,
      the password use for the creation of this account will be the same as the one used for PostgreSQL's postgres superuser account,
      creates postgres user profile,
      downloads the PostgreSQL installer provided by EnterpriseDB,
      installs Postgres unattended using the supplied parameters,
      sets postgres windows user as owner of Postgres files and folders,
      sets Postgres windows service to run under postgres local user,
      creates pgpass.conf file in AppData,
      copies configuration files to data directory,
      opens the supplied port that PostgreSQL will use in the Windows Firewall.
      
      .PARAMETER User
      Local windows user that runs pg windows service
      
      .PARAMETER Password
      Windows user password as well as pg superuser password
      
      .PARAMETER InstallerUrl
      Default value "C:\Program Files\WindowsPowerShell\Modules\Install-Postgres\postgresql-11.1-1-windows-x64.exe"
      
      .PARAMETER InstallPath
      Default value "C:\Program Files\PostgreSQL\11.1"
      
      .PARAMETER DataPath
      Default value "C:\Program Files\PostgreSQL\11.1\data"
      
      .PARAMETER Locale
      Default value "French, France"
      
      .PARAMETER Port
      Default value 5432
      
      .PARAMETER ServiceName
      Default value "postgresql"
      
      .EXAMPLE
      Install-Postgres -User postgres -Password testtest
      
      .NOTES
      You need to have administrative permissions to run this script.
      
      #>
      
      Param
      (
      [Parameter(Mandatory=$true)]
      [Alias('User')][String]$pgUser="post24",
      
      [Parameter(Mandatory=$true)]
      [Alias('Password')][String]$pgPassword="changepowershell.org",
      
      [Parameter(Mandatory=$false)]
      [Alias('InstallerUrl')][String]$pgKitSource="C:\Program Files\WindowsPowerShell\Modules\Install-Postgres\postgresql-11.1-1-windows-x64.exe",
      
      [Parameter(Mandatory=$false)]
      [Alias('InstallPath')][String]$pgInstallPath="C:\Program Files\PostgreSQL\11.1",
      
      [Parameter(Mandatory=$false)]
      [Alias('DataPath')][String]$pgDataPath="C:\Program Files\PostgreSQL\11.1\data",
      
      [Parameter(Mandatory=$false)]
      [Alias('Locale')][String]$pgLocale="French, France",
      
      [Parameter(Mandatory=$false)]
      [Alias('Port')][int]$pgPort=5432,
      
      [Parameter(Mandatory=$false)]
      [Alias('ServiceName')][String]$pgServiceName="postgresql"
      )
      
      $pgKit = "$PSScriptRoot\postgresql.exe";
      $pgConfigSource = "$PSScriptRoot\Config";
      $pgPassPath = "C:\Users\$pgUser\AppData\Roaming\postgresql";
      
      Write-Host "Starting...";
      break;
      
      Write-Host "Creating local user $pgUser" -ForegroundColor DarkGreen;
      
      try
      {
      New-LocalUser $pgUser $pgPassword;
      }
      catch
      {
      Write-Error $_.Exception.Message;
      break;
      }
      
      $script:nativeMethods = @();
      if (-not ([System.Management.Automation.PSTypeName]'NativeMethods').Type)
      {
      Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
      [MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
      [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";
      
      Add-NativeMethods;
      }
      
      $localUser = New-Object System.Security.Principal.NTAccount("$pgUser");
      $userSID = $localUser.Translate([System.Security.Principal.SecurityIdentifier]);
      $sb = new-object System.Text.StringBuilder(260);
      $pathLen = $sb.Capacity;
      
      Write-Host "Creating user profile L11 for $pgUser" -ForegroundColor DarkGreen;
      
      try
      {
      [NativeMethods]::CreateProfile($userSID.Value, $pgUser, $sb, $pathLen) | Out-Null;
      }
      catch
      {
      Write-Error $_.Exception.Message;
      break;
      }
      
      Write-Host "Installing Post L133 in $pgInstallPath Ligne 133" -ForegroundColor DarkGreen;
      
      try
      {
      Start-PostgresInstall $pgKitSource $pgKit $pgInstallPath $pgDataPath $pgLocale $pgPort $pgServiceName $pgUser $pgPassword;
      }
      catch
      {
      Write-Error $_.Exception.Message;
      break;
      }
      
      Write-Host "Grant full control of $pgInstallPath for user $pgUser" -ForegroundColor DarkGreen;
      
      try
      {
      Set-DirOwner $pgInstallPath $pgUser;
      }
      catch
      {
      Write-Error $_.Exception.Message;
      break;
      }
      
      # Write-Host "Creating pgpass.conf in $pgPassPath";
      
      # try
      # {
      # New-PgPass $pgPassPath $pgUser $pgPassword;
      # Set-Owner $pgPassPath $pgUser;
      
      # catch
      # {
      # Write-Error $_.Exception.Message;
      # break;
      # }
      
      Write-Host "Copying config files to $pgDataPath" -ForegroundColor DarkGreen;
      
      try
      {
      Copy-Configs $pgConfigSource $pgDataPath;
      }
      catch
      {
      Write-Host "Erreur ligne 174";
      Write-Error $_.Exception.Message;
      break;
      }
      
      Write-Host "Creating firewall rule for port $pgPort";
      
      try
      {
      Open-Port $pgServiceName $pgPort;
      }
      catch
      {
      Write-Error $_.Exception.Message;
      break;
      }
      
      Write-Host "Changing $serviceName windows service user to $pgUser";
      
      try
      {
      Set-ServiceOwner $pgServiceName $pgUser $pgPassword;
      }
      catch
      {
      Write-Error $_.Exception.Message;
      break;
      }
      
      Write-Host "Postgres has been installed";
      }
      
      function New-LocalUser($userName, $password)
      {
      $system = [ADSI]"WinNT://$env:COMPUTERNAME";
      $user = $system.Create("user",$userName);
      $user.SetPassword($password);
      $user.SetInfo();
      
      $flag=$user.UserFlags.value -bor 0x10000;
      $user.put("userflags",$flag);
      $user.SetInfo();
      
      # $group = [ADSI]("WinNT://$env:COMPUTERNAME/BUILTIN/Administrateurs");
      # $group.psbase.Invoke("Add", $user.psbase.Path);
      
      }
      
      function Register-NativeMethod([string]$dll, [string]$methodSignature)
      {
      $script:nativeMethods += [PSCustomObject]@{ Dll = $dll; Signature = $methodSignature; }
      }
      
      function Add-NativeMethods()
      {
      $nativeMethodsCode = $script:nativeMethods | % { "
      [DllImport(`"$($_.Dll)`")]
      public static extern $($_.Signature);
      " }
      
      Add-Type @"
      using System;
      using System.Text;
      using System.Runtime.InteropServices;
      public static class NativeMethods {
      $nativeMethodsCode
      }
      "@
      }
      
      function Start-PostgresInstall($installerUrl, $installerPath, $installPath, $dataPath, $locale, $port, $serviceName, $user, $password)
      {
      #create folders
      New-Item -ItemType Directory -Force -Path $installPath;
      New-Item -ItemType Directory -Force -Path $dataPath;
      
      # download pg installer
      Invoke-WebRequest $installerUrl -OutFile $installerPath;
      
      # run pg installer
      Start-Process $installerPath -ArgumentList "--mode unattended", "--unattendedmodeui none",`
      "--prefix `"$installPath`"", "--datadir `"$dataPath`"", "--locale `"$locale`"", "--superpassword `"$password`"",`
      "--serverport $port", "--servicename `"$serviceName`"", "--serviceaccount `"$user`"", "--servicepassword `"$password`""`
      -Wait;
      }
      
      function Set-DirOwner($path, $userName)
      {
      $acl = Get-Acl $path;
      $aclDef = "$env:COMPUTERNAME\$userName","FullControl",`
      "ContainerInherit,ObjectInherit", "InheritOnly", "Allow";
      
      $aclRule = New-Object System.Security.AccessControl.FileSystemAccessRule $aclDef;
      $acl.SetAccessRule($aclRule);
      $acl | Set-Acl $path;
      }
      
      function New-PgPass($path, $userName, $password)
      {
      New-Item -ItemType Directory -Force -Path $path;
      
      $pgPassFilePath = Join-Path $path "pgpass.conf";
      $pgPassContent = "localhost:$pgPort`:*:$userName`:$password";
      $pgPassContent | Set-Content $pgPassFilePath;
      }
      
      function Copy-Configs($configSource, $dataPath)
      {
      if ( Test-Path $pgConfigSource)
      {
      Copy-Item $pgConfigSource -Filter *.conf $dataPath -Force;
      }
      }
      
      function Open-Port($name, $port)
      {
      New-NetFirewallRule -DisplayName $name -Direction Inbound –Protocol TCP –LocalPort $port -Action allow -Profile Any;
      }
      
      function Set-ServiceOwner($serviceName, $user, $password)
      {
      $user = ".\$user";
      $service = gwmi win32_service -computer "." -filter "name='$serviceName'";
      $service.change($null,$null,$null,$null,$null,$null,$user,$password);
      $service.StopService();
      Start-Sleep -s 2;
      $service.StartService();
      }
      
      Export-ModuleMember -Function Install-Postgres;
      
       
      
      

       

       

       

       

       

       

       

       

       

       

    • #200300
      Senior Moderator
      Topics: 3
      Replies: 117
      Points: 604
      Helping Hand
      Rank: Major Contributor

      So, essentially PowerShell expected an object of the class System.Security.Principal.IdentityReference, which should be either an SID or an NTAccount name, but you gave it a System.String object, which it didn’t like. There’s some discussion of this here and here, but nothing particularly in-depth.

      I think, in order for it to work properly, you need to get PowerShell to find the matching SID for the username and feed that object in rather than just the username as a string.

      It’s possible that the script installed PostgreSQL as desired, but failed to create the user account properly due to this error.

      Ultimately, yes, there are major differences between the way that Windows 7 works and the way that Windows 10 works. PowerShell and .NET framework have also been through several revisions. You would be better off looking for a more up-to-date script.

Viewing 1 reply thread
  • You must be logged in to reply to this topic.