> ## 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.

# Escriure a un camp personalitzat d'actiu amb scripts

> Utilitzeu scripts de Gorelo per escriure valors com claus de recuperació BitLocker, contrasenyes d'administrador local rotades i UID de tercers en camps personalitzats d'actiu automàticament.

Claus BitLocker, rotació de contrasenyes d'administrador local, UID de tercers, etc.

Podeu escriure a un camp personalitzat d'actiu mitjançant scripts. Això és útil per a coses com claus BitLocker, rotació de contrasenyes d'administrador local i UID de tercers.

<Steps>
  <Step title="Creeu un camp personalitzat d'actiu">
    1. Aneu a **Configuració** > **Actius** > **Camps personalitzats**.
    2. Afegiu un camp personalitzat amb els detalls següents:

    <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="Creeu l'script">
    1. Aneu a **Scripts**.
    2. Creeu un script amb els detalls següents:

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

        ```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
        * **Contingut**:

        ```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
        * **Contingut**:

        ```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
        * **Contingut**:

        ```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
        * **Contingut**:

        ```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="Desplegueu l'script via una política.">
    1. Aneu a **[Polítiques](https://app.gorelo.io/Asset/policy-management).**
    2. Editeu una política existent que cobreixi els actius dels quals vulgueu emmagatzemar les claus o les adreces.
    3. Afegiu l'script i configureu-lo perquè es repeteixi diàriament a l'hora preferida.
    4. **Deseu** i distribuïu la política.
  </Step>
</Steps>
