diff --git a/plugins/tasks/Extractor.php b/plugins/tasks/Extractor.php
index 1ad125ed5bfe514198182a28be13b2ad817882d4..1faaa337eac2f295ce667c7a0a0ceb6b73fe4518 100644
--- a/plugins/tasks/Extractor.php
+++ b/plugins/tasks/Extractor.php
@@ -79,8 +79,8 @@ class Extractor implements EndpointInterface
         // Get main task CN for filename
         $mainTaskCn = $this->getMainTaskCn($task['fdtasksgranularmaster'][0]);
         
-        // Determine filename with main task name and date with hours
-        $date = date('Y-m-d_H-i-s');
+        // Determine filename with main task name and date with hour (no minutes or seconds)
+        $date = date('Y-m-d_H');  // Using only year-month-day_hour format
         $filename = isset($data['filename']) ? 
                    $path . $data['filename'] . '_' . $date . '.' . $format : 
                    $path . $mainTaskCn . '_' . $date . '.' . $format;
@@ -183,47 +183,99 @@ class Extractor implements EndpointInterface
    * @param string $filename
    * @return bool
    * @throws Exception
-   * Note: Export user attributes to CSV.
+   * Note: Export user attributes to CSV, preventing duplicate UIDs and handling new attributes.
    */
   private function exportToCsv(array $userAttributes, string $filename): bool
   {
-    $fileExists = file_exists($filename);
-    $handle = fopen($filename, 'a');
-    
-    if ($handle === false) {
-      throw new Exception("Could not open file: $filename");
+    if (empty($userAttributes)) {
+      return true; // No attributes to write
     }
     
-    try {
-      if (empty($userAttributes)) {
-        return true; // No attributes to write
+    $user = $userAttributes[0];
+    $userData = [];
+    $allColumns = [];
+    $existingData = [];
+    $uidKey = 'uid'; // The attribute to check for duplicates
+    $newUserUid = '';
+    
+    // Extract UID and prepare user data
+    foreach ($user as $attribute => $values) {
+      if (is_array($values)) {
+        foreach ($values as $key => $value) {
+          if (is_numeric($key)) {
+            $userData[$attribute] = $value;
+            $allColumns[$attribute] = true; // Use as associative array to avoid duplicates
+            
+            if (strtolower($attribute) === $uidKey) {
+              $newUserUid = $value;
+            }
+            
+            break; // Only take the first value for simplicity
+          }
+        }
       }
-      
-      $user = $userAttributes[0];
-      $columns = [];
-      $data = [];
-      
-      // Prepare columns and data
-      foreach ($user as $attribute => $values) {
-        if (is_array($values)) {
-          foreach ($values as $key => $value) {
-            if (is_numeric($key)) {
-              $columns[] = $attribute;
-              $data[] = $value;
-              break; // Only take the first value for simplicity
+    }
+    
+    // If no UID found, generate a random one
+    if (empty($newUserUid)) {
+      $newUserUid = 'user_' . uniqid();
+      $userData[$uidKey] = $newUserUid;
+      $allColumns[$uidKey] = true;
+    }
+    
+    // Read existing file if it exists
+    if (file_exists($filename)) {
+      $handle = fopen($filename, 'r');
+      if ($handle !== false) {
+        // Read headers
+        $headers = fgetcsv($handle);
+        if ($headers !== false) {
+          // Add existing headers to all columns
+          foreach ($headers as $header) {
+            $allColumns[$header] = true;
+          }
+          
+          // Read existing data
+          while (($row = fgetcsv($handle)) !== false) {
+            $rowData = [];
+            foreach ($headers as $index => $header) {
+              $rowData[$header] = $row[$index] ?? '';
+            }
+            // Only add to existing data if it's not the same UID as new user
+            if (isset($rowData[$uidKey]) && $rowData[$uidKey] !== $newUserUid) {
+              $existingData[] = $rowData;
             }
           }
         }
+        fclose($handle);
       }
+    }
+    
+    // Convert all columns associative array to indexed array
+    $finalColumns = array_keys($allColumns);
+    
+    // Add new user data to existing data
+    $existingData[] = $userData;
+    
+    // Write to file
+    $handle = fopen($filename, 'w'); // 'w' to overwrite with complete data
+    if ($handle === false) {
+      throw new Exception("Could not open file: $filename");
+    }
+    
+    try {
+      // Write headers
+      fputcsv($handle, $finalColumns);
       
-      // Write header if file is new
-      if (!$fileExists) {
-        fputcsv($handle, $columns);
+      // Write data rows
+      foreach ($existingData as $row) {
+        $outputRow = [];
+        foreach ($finalColumns as $column) {
+          $outputRow[] = $row[$column] ?? ''; // Use empty string if attribute not found
+        }
+        fputcsv($handle, $outputRow);
       }
       
-      // Write data
-      fputcsv($handle, $data);
-      
       return true;
     } finally {
       fclose($handle);
@@ -234,17 +286,31 @@ class Extractor implements EndpointInterface
    * @param array $userAttributes
    * @param string $filename
    * @return bool
-   * Note: Export user attributes to JSON.
+   * Note: Export user attributes to JSON with duplicate UID handling.
    */
   private function exportToJson(array $userAttributes, string $filename): bool
   {
     $existingData = [];
+    $uidKey = 'uid';
+    $newUserUid = '';
+    
+    // Get UID of new user
+    if (!empty($userAttributes[0][$uidKey][0])) {
+      $newUserUid = $userAttributes[0][$uidKey][0];
+    }
     
     // Read existing data if file exists
     if (file_exists($filename)) {
       $existingJson = file_get_contents($filename);
       if (!empty($existingJson)) {
-        $existingData = json_decode($existingJson, true) ?? [];
+        $jsonData = json_decode($existingJson, true) ?? [];
+        
+        // Filter out any entries with the same UID
+        foreach ($jsonData as $entry) {
+          if (!isset($entry[$uidKey][0]) || $entry[$uidKey][0] !== $newUserUid) {
+            $existingData[] = $entry;
+          }
+        }
       }
     }
     
@@ -259,17 +325,35 @@ class Extractor implements EndpointInterface
    * @param array $userAttributes
    * @param string $filename
    * @return bool
-   * Note: Export user attributes to XML.
+   * Note: Export user attributes to XML with duplicate UID handling.
    */
   private function exportToXml(array $userAttributes, string $filename): bool
   {
     $dom = new DOMDocument('1.0', 'UTF-8');
     $dom->formatOutput = true;
+    $uidKey = 'uid';
+    $newUserUid = '';
     
-    // Create root element if file doesn't exist
+    // Get UID of new user
+    if (!empty($userAttributes[0][$uidKey][0])) {
+      $newUserUid = $userAttributes[0][$uidKey][0];
+    }
+    
+    // Create or load XML document
     if (file_exists($filename)) {
       $dom->load($filename);
       $root = $dom->documentElement;
+      
+      // Remove any existing user with the same UID
+      if (!empty($newUserUid)) {
+        $xpath = new DOMXPath($dom);
+        $users = $xpath->query("/users/user[{$uidKey}='{$newUserUid}']");
+        if ($users->length > 0) {
+          foreach ($users as $user) {
+            $root->removeChild($user);
+          }
+        }
+      }
     } else {
       $root = $dom->createElement('users');
       $dom->appendChild($root);