Office(R)Tool Project

Discussion in 'Microsoft Office' started by Dark Dinosaur, Nov 6, 2021.

?

Change brand name or not ?

Poll closed Dec 26, 2021.
  1. No, keep it like that

    148 vote(s)
    75.1%
  2. Yes, officeRTool need fresh name

    49 vote(s)
    24.9%
  1. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    maybe my guide is not so good .. :D
    upload_2024-1-11_21-36-10.png
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. gefexad

    gefexad MDL Novice

    Jan 11, 2024
    3
    0
    0
    :sorry: always used the online installer before and never saw those
     
  3. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    Online choice is good ..
    I prefer the 21 version..Instead 365 application
    Currently use 2024 preview
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. gefexad

    gefexad MDL Novice

    Jan 11, 2024
    3
    0
    0
    Tried and seems to be working, thank you :clap:

    Also prefer 21 version, don't need to store in the cloud or anything like that, nor use any email. But need to use some excel functions only available in 365.

    Couple of questions, what's the purpose of the "enable visual ui with lstc logo" in officertool? And regarding "disable acquisition and telemetry", i understand it always keep it off, no matter how many times i run it, right? Or it enable/disable it everytime?
     
  5. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    #1965 Dark Dinosaur, Jan 12, 2024
    Last edited: Jan 12, 2024
    (OP)
    A. Round edges in 2019 2021
    B. Privacy
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    I do some testing, if any differences in speed
    I can say that Invoke-CimMethod is less code to write than gwmi

    Invoke-CimMethod
    Code:
    if ($Args[0] -eq '/InstallProductKey') {
     $KEY  = $Args[1]
     $ErrorActionPreference = "Stop"
    
    gwmi
     try {
      Invoke-CimMethod -MethodName InstallProductKey -Query "select * from SoftwareLicensingService" -Arguments @{ProductKey=$KEY}
      return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
    Code:
    if ($Args[0] -eq '/InstallProductKey') {
     $KEY  = $Args[1]
     $ErrorActionPreference = "Stop"
     $LicensingService = gwmi -ClassName SoftwareLicensingService -ErrorAction SilentlyContinue
     if (-not $LicensingService) {
        return "Error:CLASS_NOT_FOUND"
     }
     try {
      $LicensingService.InstallProductKey($KEY)
      return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
    the same thing in License install

    how much code is needed here?!
    Code:
    if ($Args[0] -eq '/InstallLicense') {
     $LicenseFile      = $Args[1]
     $ErrorActionPreference = "Stop"
     if([System.IO.File]::Exists($LicenseFile)-ne $true) {
        return "Error:FILE_NOT_FOUND"
     }
     $LicensingService = gwmi -ClassName SoftwareLicensingService -ErrorAction SilentlyContinue
     if (-not $LicensingService) {
        return "Error:CLASS_NOT_FOUND"
     }
     try {
      $LicensingService.InstallLicense(
       [System.IO.File]::ReadAllText(
         $LicenseFile
      ))
      return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
    
    and with the second method
    Code:
    if ($Args[0] -eq '/InstallLicense') {
     $LicenseFile      = $Args[1]
     $ErrorActionPreference = "Stop"
     
     if([System.IO.File]::Exists($LicenseFile)-ne $true) {
        return "Error:FILE_NOT_FOUND"
     }
    
     try {
      Invoke-CimMethod -MethodName InstallLicense -Query "select * from SoftwareLicensingService" -Arguments @{License="$([System.IO.File]::ReadAllText($LicenseFile))"}
      return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
     

    Attached Files:

    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. KleineZiege

    KleineZiege MDL Expert

    Dec 11, 2018
    1,854
    2,111
    60
    why don't you use YAOCTRU_v9.0

    all unlocks here are based on the original from MDL
     
  8. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    after little testing
    manage to remove and short lot of code
    the bare minimum code for WMI operation
    I hope it will improve the speed too.

    Code:
    the shortest code in PS to activate a product
    iwmi -Path "$($CLASS).ID='$($ID)'" -Name Activate
    
    the shortest code in PS to install a license
    gwmi -Class SoftwareLicensingService | iwmi -Name InstallLicense -Args @([System.IO.File]::ReadAllText($LicenseFile))
    
    the shortest code in PS to install/uninstall a product key
    gwmi -Class SoftwareLicensingService | iwmi -Name InstallProductKey -Args $KEY
    icim -MethodName UninstallProductKey -Query "select * from $($CLASS) where ($($FILTER))"
    
    Full Code
    Code:
    if ($Args[0] -eq '/QUERY_BASIC') {
     $class = $Args[2];
     $value = @($Args[1]).Replace(' ','')
     $wmi_Object = gwmi -Query "select $($value) from $($class)" -ErrorAction SilentlyContinue
     if (-not $wmi_Object) {
       return "Error:WMI_SEARCH_FAILURE"
     }
     foreach ($item in $wmi_Object) {
      $line = '';
      $value.Split(",")|%{$line += ",$($item.GetPropertyValue("$_"))"}
      Write-Host $line
     }
     return
    }
    
    if ($Args[0] -eq '/QUERY_ADVENCED') {
     $class  = $Args[2];
     $filter = $Args[3];
     $value  = @($Args[1]).Replace(' ','')
     $wmi_Object = gwmi -Query "select $($value) from $($class) where ($($filter))" -ErrorAction SilentlyContinue
     if (-not $wmi_Object) {
       return "Error:WMI_SEARCH_FAILURE"
     }
     foreach ($item in $wmi_Object) {
      $line = '';
      $value.Split(",")|%{$line += ",$($item.GetPropertyValue("$_"))"}
      Write-Host $line
     }
     return
    }
    
    if ($Args[0] -eq '/ACTIVATE') {
     $CLASS = $Args[1]
     $ID    = $Args[2]
     $ErrorActionPreference = "Stop"
      try {
       iwmi -Path "$($CLASS).ID='$($ID)'" -Name Activate
       return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
    
    if ($Args[0] -eq '/UninstallProductKey') {
     $CLASS  = $Args[1]
     $FILTER = $Args[2]
    
     try {
       icim -MethodName UninstallProductKey -Query "select * from $($CLASS) where ($($FILTER))"
       return "Error:0"
      }
     catch {
       # return wmi last error, in hex format
       $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
       return "Error:$($HResult)"
     }
    }
    
    if ($Args[0] -eq '/InstallProductKey') {
     $KEY  = $Args[1]
     $ErrorActionPreference = "Stop"
    
     try {
      gwmi -Class SoftwareLicensingService | iwmi -Name InstallProductKey -Args $KEY
      return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
    
    if ($Args[0] -eq '/InstallLicense') {
     $LicenseFile      = $Args[1]
     $ErrorActionPreference = "Stop"
     
     if([System.IO.File]::Exists($LicenseFile)-ne $true) {
        return "Error:FILE_NOT_FOUND"
     }
    
     try {
      gwmi -Class SoftwareLicensingService | iwmi -Name InstallLicense -Args @([System.IO.File]::ReadAllText($LicenseFile))
      return "Error:0"
     }
     catch {
      # return wmi last error, in hex format
      $HResult = ‘{0:x}’ -f  @($_.Exception).HResult
      return "Error:$($HResult)"
     }
    }
    
    return $null
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    #1969 Dark Dinosaur, Jan 14, 2024
    Last edited: Jan 14, 2024
    (OP)
    so I sit in this thing today.
    and managed to make it even more compact
    about `Activate` I think I can't make it -
    more compact than it is now
    it good for the experience with PS WMI
    Code:
    iwmi -Path "$($CLASS).ID='$($ID)'" -Name Activate
    gcim $CLASS -filter "ID='$($ID)'" | icim -Name Activate
    
    gwmi SoftwareLicensingService | % {$_.InstallProductKey($KEY)}
    gwmi -Class SoftwareLicensingService | iwmi -Name InstallProductKey -Args $KEY
    
    gwmi SoftwareLicensingService | % {$_.InstallLicense(@([System.IO.File]::ReadAllText($LicenseFile)))}
    gwmi -Class SoftwareLicensingService | iwmi -Name InstallLicense -Args @([System.IO.File]::ReadAllText($LicenseFile))
    
    That's what I got so far ...
    after a lot of trial and error with icim\gcim & gwmi\iwmi
    Code:
    Using Filter\Path
    iwmi -Path "$($CLASS).ID='$($ID)'" -Name Activate
    gcim $CLASS -filter "ID='$($ID)'" | icim -Name Activate
    Using Query
    icim -Name Activate -Query "select * from $($CLASS) where (ID='$($ID)')"
    gwmi -Query "select * from $($CLASS) where ID='$($ID)'" | % {$_.Activate()}
    
    ....... After .. after ...

    Using [wmi] tag I was able to make it
    Even more compact
    For static class it's the best solution
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  10. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    #1970 Dark Dinosaur, Jan 19, 2024
    Last edited: Jan 19, 2024
    (OP)
    Something that builds as an Idea...
    will get the office licenses, clean all licenses, and re-added them again.
    Output. here.

    Code:
    ### Found license: VisioPro2024PreviewVL_KMS_Client_AE
    ### Found license: ProjectPro2024PreviewVL_KMS_Client_AE
    ### Found license: ProPlus2024PreviewVL_KMS_Client_AE
    
    Un-install license: 0990975c-d5c4-eb88-bc84-0ba4fc7ff1b9
    Un-install license: 0b7faf31-c4a8-a8ae-a034-a266db487f08
    Un-install license: 1d435f47-bea8-5891-7674-dd1d3e03c490
    Un-install license: 215ad112-94d6-9157-11a2-d25123930edb
    Un-install license: 4bada8e2-5ec8-a135-449d-2849b6c8d5eb
    Un-install license: 73e79f34-ec45-ecb3-7d11-eb6723c9f5d6
    Un-install license: 7aa92662-74e0-1bab-eaed-0e3e6b9f0ae9
    Un-install license: bcc975a5-233d-f352-c92a-d501fef591fc
    Un-install license: bf838077-8faa-ef02-c3bf-998827d894ae
    Un-install license: fda4f580-bbce-b75d-85ef-75daa9fc8507
    Un-install license: fdf82507-1037-cb40-219b-fe56da5e5598
    
    Re-Install License: pkeyconfig-office.xrm-ms
    Re-Install License: pkeyconfig-office-client15.xrm-ms
    Re-Install License: client-issuance-root.xrm-ms
    Re-Install License: client-issuance-stil.xrm-ms
    Re-Install License: client-issuance-ul.xrm-ms
    Re-Install License: client-issuance-ul-oob.xrm-ms
    Re-Install License: client-issuance-root-bridge-test.xrm-ms
    Re-Install License: client-issuance-bridge-office.xrm-ms
    Re-Install License: VisioPro2024PreviewVL_KMS_Client_AE.xrm-ms
    Re-Install License: ProjectPro2024PreviewVL_KMS_Client_AE-ul-oob.xrm-ms
    Re-Install License: ProPlus2024PreviewVL_KMS_Client_AE-ul-oob.xrm-ms
    
    v2.0
    Code:
    cls
    Write-Host
    
    $InstallPath = $null
    $LicenseList = $null
    $ServiceClass =  gwmi SoftwareLicensingService
    $InstallPath_X64 = Get-ItemProperty -path "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun" -Name "InstallPath" -ea 0
    $InstallPath_X86 = Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Office\ClickToRun" -Name "InstallPath" -ea 0
    
    if ($InstallPath_X64 -and (Test-path $InstallPath_X64.InstallPath)) {
      $InstallPath = $InstallPath_X64.InstallPath }
    if ($InstallPath_X86 -and (Test-path $InstallPath_X86.InstallPath)) {
      $InstallPath = $InstallPath_X86.InstallPath }
    if (-not $InstallPath) {
      return }
    
    # Get licenses
    $LicenseWMI = (GWMI SoftwareLicensingProduct -ErrorAction SilentlyContinue)|? ApplicationId -EQ '0ff1ce15-a989-479d-af46-f275c6370663'| ? LicenseIsAddon -EQ $false
    if (-not $LicenseWMI) {
      return }
    $LicenseList = $LicenseWMI.Name.Substring(19).Replace(' edition',' ')
    $Client_List  = "pkeyconfig-office.xrm-ms,pkeyconfig-office-client15.xrm-ms,client-issuance-root.xrm-ms,client-issuance-stil.xrm-ms,client-issuance-ul.xrm-ms,client-issuance-ul-oob.xrm-ms,client-issuance-root-bridge-test.xrm-ms,client-issuance-bridge-office.xrm-ms"
    
    $LicenseList | % {
      "### Found license: $($_)" }
    Write-Host
    
    # Clean licenses
    try {
    $compilerParameters = New-Object -TypeName CodeDom.Compiler.CompilerParameters
    $compilerParameters.CompilerOptions = '/unsafe'
    
    Add-Type -CompilerParameters $compilerParameters @"
    using System;
    using System.Runtime.InteropServices;
    
    public class API
    { 
        unsafe delegate uint SLOpenDelegate(void** phSLC);
        unsafe delegate uint SLGetSLIDListDelegate(void* hSLC, int eQueryIdType, Guid* pQueryId, int eReturnIdType, uint* pnReturnIds, Guid** ppReturnIds);
        unsafe delegate uint SLUninstallLicenseDelegate(void* hSLC, Guid* pLicenseFileId);
      
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string path);
    
        [DllImport("kernel32.dll")]
        static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    
        public static void CleanLicenses()
        {
            UninstallLicenses("sppc");
            string ospp = (string)Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\OfficeSoftwareProtectionPlatform", "Path", null);
            if (ospp != null)
            {
                Console.WriteLine("Found Office Software Protection installed, cleaning");
                UninstallLicenses(ospp + "osppc.dll");
            }
        }
    
        public static void UninstallLicenses(string dllPath)
        {
            IntPtr sppc = LoadLibrary(dllPath);
            SLOpenDelegate open = (SLOpenDelegate)Marshal.GetDelegateForFunctionPointer(GetProcAddress(sppc, "SLOpen"), typeof(SLOpenDelegate));
            SLGetSLIDListDelegate getSLIDList = (SLGetSLIDListDelegate)Marshal.GetDelegateForFunctionPointer(GetProcAddress(sppc, "SLGetSLIDList"), typeof(SLGetSLIDListDelegate));
            SLUninstallLicenseDelegate uninstallLicense = (SLUninstallLicenseDelegate)Marshal.GetDelegateForFunctionPointer(GetProcAddress(sppc, "SLUninstallLicense"), typeof(SLUninstallLicenseDelegate));
    
            unsafe
            {
                void* phSLC;
                open(&phSLC);
                uint pnReturnIds;
                Guid* ppReturnIds;
                Guid officeGuid = new Guid("0ff1ce15-a989-479d-af46-f275c6370663");
                if (getSLIDList(phSLC, 0, &officeGuid, 6, &pnReturnIds, &ppReturnIds) != 0)
                {
                    return;
                }
    
                for (int i = 0; i < pnReturnIds; i++)
                {
                    Console.WriteLine("Un-install license: " + ppReturnIds[i]);
                    uninstallLicense(phSLC, &ppReturnIds[i]);
                }
            }
        }
    }
    "@
    }
    catch {
      return }
    
    [API]::CleanLicenses()
    
    # Restore licenses
    Write-Host
    $Client_List.Split(",") |% {
      $LicenseFile = Join-Path $InstallPath "root\Licenses16\$($_)"
      if (Test-Path $LicenseFile) {
          "Re-Install License: $($_)"
          $ServiceClass.InstallLicense(@([IO.File]::ReadAllText($LicenseFile))) | Out-Null
    }}
    
    $LicenseList |% {
      $LicenseName = "$($_)".Replace(" ","")
      $LicenseFile = Join-Path $InstallPath "root\Licenses16\$($LicenseName)"
      "Re-Install License: $($LicenseName)$($patteren).xrm-ms"
      foreach ($patteren in "-ppd,-ul,-ul-oob".Split(',')) {
        if (Test-Path "$($LicenseFile)$($patteren).xrm-ms") {
          $ServiceClass.InstallLicense(@([IO.File]::ReadAllText("$($LicenseFile)$($patteren).xrm-ms"))) | Out-Null
      }}
    }
    return
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  11. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    Forget to add a replacement alternative to '/rilc' & '/ato'
    so build a new PS code for that, using the original one from SLMGR.vbs
    and in insider build, convert will use PS code instead vbs

    Code:
      # Private Sub ReinstallLicenses()
      #   strOemFolder = shell.ExpandEnvironmentStrings("%SystemRoot%") & "\system32\oem"
      #   strSppTokensFolder = shell.ExpandEnvironmentStrings("%SystemRoot%") & "\system32\spp\tokens"
      #   Set folder = fso.GetFolder(strSppTokensFolder)
      #   For Each subFolder in folder.SubFolders
      #       InstallLicenseFiles subFolder, fso
      #   Next
      #   If (fso.FolderExists(strOemFolder)) Then
      #       InstallLicenseFiles strOemFolder, fso
      #   End If
      # End Sub
    
    to this
    Code:
     $LicensingService = GWMI SoftwareLicensingService -ErrorAction Stop
      if (-not $LicensingService) {
        return }
    
     $OEM    = Join-Path $ENV:SystemRoot "system32\oem"
     $tokens = Join-Path $ENV:SystemRoot "system32\spp\tokens"
     
     if (Test-Path $tokens) {
       dir $tokens -Filter *.xrm-ms -Recurse -Name | % {
         $LicenseFile = Join-Path $tokens $_
         if (Test-Path $LicenseFile) {
           $LicensingService.InstallLicense([IO.FILE]::ReadAllText($LicenseFile))
     }}}
     if (Test-Path $OEM) {
       dir $OEM -Filter *.xrm-ms -Recurse -Name | % {
         $LicenseFile = Join-Path $tokens $_
         if (Test-Path $LicenseFile) {
           $LicensingService.InstallLicense([IO.FILE]::ReadAllText($LicenseFile))
     }}}
    
    and also
    Code:
      #objProduct.Activate()
      #objService.RefreshLicenseStatus()
      #objProduct.refresh_
    
    to this
    Code:
      $LicensingService = GWMI SoftwareLicensingService -ErrorAction Stop
      $LicensingProduct = gwmi -Query "select * from SoftwareLicensingProduct where (ApplicationId='55c92734-d682-4d71-983e-d6ec3f16059f' and PartialProductKey is not null)" -ErrorAction Stop
      if (-not $LicensingProduct) {
        return }
      if (-not $LicensingService) {
        return }
      $LicensingProduct.Activate()
      $LicensingService.RefreshLicenseStatus()
      $LicensingProduct.refresh_
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  12. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Is there a difference between installing Microsoft 365 Home Premium and convert and activate it to get Microsoft Office Mondo 2016 and install Microsoft Office Mondo 2016 right away?

    Also, is Microsoft 365 Home Premium actually called Microsoft 365 Family?
     
  13. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    Each License equ different features
    I would say, if you want to enjoy 365
    Use sub discription account
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  14. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Sorry, I don't understand what you mean.
     
  15. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  16. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    Mondo license and 365 license
    are different products With different features
    If you prefer using 365 ...
    You can consider buy a sub description
    But if not, it will convert to mondo license
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  17. Windows 10 User

    Windows 10 User MDL Guru

    Feb 2, 2017
    2,005
    122
    90
    Is OfficeRTool's Microsoft 365 Home Premium actually called Microsoft 365 Family?
     
  18. Dark Dinosaur

    Dark Dinosaur X Æ A-12

    Feb 2, 2011
    4,171
    5,978
    150
    #1980 Dark Dinosaur, Jan 20, 2024
    Last edited: Jan 20, 2024
    (OP)
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...