> ## Documentation Index
> Fetch the complete documentation index at: https://help.gorelo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Écrire dans un champ personnalisé d'actif avec des scripts

> Utilisez les scripts Gorelo pour écrire des valeurs comme les clés de récupération BitLocker, les mots de passe d'administrateur local renouvelés et les UID tiers dans les champs personnalisés d'actifs automatiquement.

Clés BitLocker, rotation des mots de passe d'administrateur local, UID tiers, etc.

Vous pouvez écrire dans un champ personnalisé d'actif via des scripts. C'est utile pour des choses comme les clés BitLocker, la rotation des mots de passe d'administrateur local et les UID tiers.

<Steps>
  <Step title="Créer un champ personnalisé d'actif">
    1. Allez à **Paramètres** > **Actifs** > **Champs personnalisés**.
    2. Ajoutez un champ personnalisé avec les détails suivants :

    <Tabs>
      <Tab title="BitLocker">
        * **Nom** : BitLocker Recovery Key
        * **Variable** : bitlockerRecoveryKey

        <Frame>
          <img src="https://mintcdn.com/gorelo/hTBX2qpHbjxDttw-/images/image-116.png?fit=max&auto=format&n=hTBX2qpHbjxDttw-&q=85&s=2319913d92820567f3479e8016569176" alt="Image" width="778" height="619" data-path="images/image-116.png" />
        </Frame>
      </Tab>

      <Tab title="Windows Install Date">
        * **Nom** : Windows Install Date
        * **Variable** : windowsInstallDate

        <Frame>
          <img src="https://mintcdn.com/gorelo/hTBX2qpHbjxDttw-/images/image-110.png?fit=max&auto=format&n=hTBX2qpHbjxDttw-&q=85&s=10e3f1f3314306dba75c38d4701feb7c" alt="Image" width="787" height="606" data-path="images/image-110.png" />
        </Frame>
      </Tab>

      <Tab title="Windows Product Key">
        * **Nom** : Windows Product Key
        * **Variable** : windowsProductKey

        <Frame>
          <img src="https://mintcdn.com/gorelo/vUQ8OM8P3jBMi8Dq/images/image-118.png?fit=max&auto=format&n=vUQ8OM8P3jBMi8Dq&q=85&s=1dfb76668303d54756404bee5f0fbf4d" alt="Image" width="781" height="603" data-path="images/image-118.png" />
        </Frame>
      </Tab>

      <Tab title="MAC Address">
        * **Nom** : MAC Address
        * **Variable** : macAddress

        <Frame>
          <img src="https://mintcdn.com/gorelo/fI4EZlX_4VIJ5gmy/images/image-119.png?fit=max&auto=format&n=fI4EZlX_4VIJ5gmy&q=85&s=5515c35750de344cd60cb7c3d62b4ee1" alt="Image" width="793" height="630" data-path="images/image-119.png" />
        </Frame>
      </Tab>

      <Tab title="RAM Slots Used">
        * **Nom** : RAM Slots Used
        * **Variable** : ramSlotsUsed

        <Frame>
          <img src="https://mintcdn.com/gorelo/l3kfLaTp3Zy4uEi2/images/image-121.png?fit=max&auto=format&n=l3kfLaTp3Zy4uEi2&q=85&s=eb10f33b94faeaa1bf5b8441ff39ce97" alt="Image" width="786" height="602" data-path="images/image-121.png" />
        </Frame>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Créer le script">
    1. Allez à **Scripts**.
    2. Créez un script avec les détails suivants :

    <Tabs>
      <Tab title="BitLocker">
        * **Nom** : 🗝️Store-BitlockerRecoveryKey
        * **Contenu** :

        ```powershell theme={null}
        $ErrorActionPreference = 'SilentlyContinue' 

        # Get drives where BitLocker is "On" 
        $BitlockerDrives = Get-BitLockerVolume | Where-Object ProtectionStatus -EQ "On" -ErrorAction SilentlyContinue

        #Get FileSystem drives 
        $Drives = Get-PSDrive -PSProvider FileSystem

        #Create array of Drive Names with ":" added
        $DrivesName = @()
        $Drives |  foreach {$DrivesName += $_.name + ':' }

        #If any Bitlockered drives exist
        if($BitlockerDrives){

            #Foreach Drive
            Foreach ($DriveName in $DrivesName) {

                #Confirm is drive is bitlockered
                $BitlockerDrive = $BitlockerDrives | where { $DriveName -contains $_ }

                #If specific drive is bitlockered
                if ($BitlockerDrive){

                    #Get RecoveryKey 
                    $RecoveryKey = $BitlockerDrive.KeyProtector | Where-Object RecoveryPassword -NE "" | Select-Object -ExpandProperty RecoveryPassword -ErrorAction SilentlyContinue
              
                    #Join if multiple with ; delimiter 
                    $RecoveryKey = $RecoveryKey -join ";"

                    #Add the drive letter to the output
                    $RecoveryKey = "$($BitlockerDrive.mountpoint)$RecoveryKey"

                    #Add to other drive keys (If exist)
                    $RecoveryKeys += " $RecoveryKey "

                } else { $RecoveryKeys += $DriveName + "Not Enabled" }   
                
            }

            GoreloAction -SetCustomField -Name 'asset.bitlockerRecoveryKey' -Value $RecoveryKeys

        #If no bitlockered drives found
        }else { 
            
            Foreach ($DriveName in $DrivesName) { 
                
                $RecoveryKeys += $DriveName + "Not Enabled " 
                
            } 
            
            GoreloAction -SetCustomField -Name 'asset.bitlockerRecoveryKey' -Value $RecoveryKeys 
            
        }
        ```
      </Tab>

      <Tab title="Windows Install Date">
        * **Nom** : 🗝️Store-WindowsInstallDate
        * **Contenu** :

        ```powershell theme={null}
        # Initialize array to store all valid dates
        $allDates = @()

        # Method 1: Win32_OperatingSystem class
        $osInfo = Get-WmiObject Win32_OperatingSystem
        $installDate = $osInfo.ConvertToDateTime($osInfo.InstallDate)
        $allDates += $installDate
        Write-Host "OS Installation Date (from Win32_OperatingSystem): $($installDate.ToString('MM/dd/yyyy'))" -ForegroundColor White

        # Method 2: Registry installation date
        $registryPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
        $registryInstallDate = Get-ItemProperty -Path $registryPath | Select-Object -ExpandProperty InstallDate
        $registryInstallDateTime = (Get-Date "1970-01-01 00:00:00.000Z").AddSeconds($registryInstallDate)
        $allDates += $registryInstallDateTime
        Write-Host "Registry Installation Date: $($registryInstallDateTime.ToString('MM/dd/yyyy'))" -ForegroundColor White

        # Method 3: Earliest system restore point (with proper date parsing)
        try {
            $restorePoints = Get-ComputerRestorePoint | Sort-Object -Property CreationTime
            if ($restorePoints) {
                $earliestRestorePoint = [datetime]::ParseExact($restorePoints[0].CreationTime.ToString(), "yyyyMMddHHmmss.ffffff-000", $null)
                $allDates += $earliestRestorePoint
                Write-Host "Earliest System Restore Point: $($earliestRestorePoint.ToString('MM/dd/yyyy'))" -ForegroundColor White
            }
        }
        catch {
            Write-Host "Unable to retrieve or parse system restore points." -ForegroundColor Yellow
        }

        # Method 4: Windows.old folder date (if exists)
        $windowsOldPath = "$env:SystemDrive\Windows.old"
        if (Test-Path $windowsOldPath) {
            $windowsOldDate = (Get-Item $windowsOldPath).CreationTime
            $allDates += $windowsOldDate
            Write-Host "Windows.old Folder Creation Date: $($windowsOldDate.ToString('MM/dd/yyyy'))" -ForegroundColor White
        }

        # Filter out any null dates and find the oldest
        $validDates = $allDates | Where-Object { $_ -ne $null }
        $oldestDate = $validDates | Sort-Object | Select-Object -First 1

        Write-Host "`nOldest detected date (likely original deployment): $($oldestDate.ToString('MM/dd/yyyy'))" -ForegroundColor Green

        # Format date for Gorelo (date only)
        $goreloDateString = Get-Date $oldestDate -Format "yyyy-MM-dd"

        # Set Gorelo custom field with the oldest date
        try {
            GoreloAction -SetCustomField -Name '$gorelo:asset.windowsInstallDate' -Value $goreloDateString
            Write-Host "Successfully updated Gorelo custom field" -ForegroundColor Green
        } catch {
            Write-Host "Error updating Gorelo custom field: $($_.Exception.Message)" -ForegroundColor Red
        }

        # Display difference between oldest and newest dates for verification
        $newestDate = $validDates | Sort-Object | Select-Object -Last 1
        $dateDifference = New-TimeSpan -Start $oldestDate -End $newestDate
        Write-Host "`nDate range span: $($dateDifference.Days) days" -ForegroundColor Cyan
        Write-Host "Newest date found: $($newestDate.ToString('MM/dd/yyyy'))" -ForegroundColor Cyan
        ```
      </Tab>

      <Tab title="Windows Product Key">
        * **Nom** : 🗝️Store-WindowsProductKey
        * **Contenu** :

        ```powershell theme={null}
        # Get Windows Product Key and update Gorelo custom field
        try {
            # Get Windows Product Key using WMI
            $productKey = (Get-WmiObject -query 'select * from SoftwareLicensingService').OA3xOriginalProductKey

            if ([string]::IsNullOrEmpty($productKey)) {
                # If OA3xOriginalProductKey is empty, try getting it from registry
                $regPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform'
                $regValue = 'BackupProductKeyDefault'
                $productKey = (Get-ItemProperty -Path $regPath -Name $regValue -ErrorAction SilentlyContinue).$regValue
            }

            if ([string]::IsNullOrEmpty($productKey)) {
                # If still empty, try another registry method
                $regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"
                $digitalId = (Get-ItemProperty -Path $regPath).DigitalProductId
                
                # Convert Digital Product ID to Product Key
                $keyOffset = 52
                $isWin8 = ([math]::Floor($digitalId[66] / 6) -band 1)
                $productKey = ""
                $chars = "BCDFGHJKMPQRSTVWXY2346789"

                for ($i = 24; $i -ge 0; $i--) {
                    $r = 0
                    for ($j = 14; $j -ge 0; $j--) {
                        $r = ($r * 256) -bxor $digitalId[$j + $keyOffset]
                        $digitalId[$j + $keyOffset] = [math]::Floor($r / 24)
                        $r = $r % 24
                    }
                    $productKey = $chars[$r] + $productKey
                    if (($i % 5) -eq 0 -and $i -ne 0) {
                        $productKey = "-" + $productKey
                    }
                }
            }

            if (![string]::IsNullOrEmpty($productKey)) {
                # Update Gorelo RMM custom field
                GoreloAction -SetCustomField -Name '$gorelo:asset.WindowsProductKey' -Value $productKey
                Write-Output "Successfully updated Windows Product Key in Gorelo"
            } else {
                Write-Error "Could not retrieve Windows Product Key"
                exit 1
            }
        } catch {
            Write-Error "Error: $($_.Exception.Message)"
            exit 1
        }
        ```
      </Tab>

      <Tab title="MAC Address">
        * **Nom** : MAC Address for Ethernet
        * **Contenu** :

        ```powershell theme={null}
        # Get Ethernet adapter MAC address only
        $MacAddress = (Get-NetAdapter | Where-Object {$_.Name -like "*Ethernet*" -and $_.Status -eq "Up"} | Select-Object -First 1 -ExpandProperty MacAddress)

        if ($MacAddress) {
            GoreloAction -SetCustomField -Name 'asset.macAddress' -Value $MacAddress
            Write-Host "Ethernet MAC Address set to: $MacAddress"
        } else {
            Write-Host "No active Ethernet adapter found"
        }
        ```
      </Tab>

      <Tab title="RAM Slots Used">
        * **Nom** : 🗝️Store-ramSlotsUsed
        * **Contenu** :

        ```powershell theme={null}
        $totalSlots = (Get-CimInstance -ClassName Win32_PhysicalMemoryArray).MemoryDevices
        $usedSlots = (Get-CimInstance -ClassName Win32_PhysicalMemory).Count
        $emptySlots = $totalSlots - $usedSlots
        $totalRAM = [math]::Round((Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory/1GB, 2)

        $ramInfo = "RAM: $totalRAM GB installed | Slots: $usedSlots/$totalSlots used ($emptySlots empty)"

        # Set Gorelo RMM custom field
        GoreloAction -SetCustomField -Name 'asset.ramSlotsUsed' -Value $ramInfo

        Write-Host "Set Gorelo field 'asset.ramSlotsUsed' to: $ramInfo"
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Déployer le script via une politique.">
    1. Allez à **[Politiques](https://app.gorelo.io/Asset/policy-management)**.
    2. Modifiez une politique existante qui couvre les actifs pour lesquels vous voulez stocker les clés ou les adresses.
    3. Ajoutez le script et configurez-le pour qu'il se répète quotidiennement à l'heure de votre choix.
    4. **Enregistrez** et distribuez la politique.
  </Step>
</Steps>
