TechED 2012 Europe: la meilleure session

Les techED sont maintenant terminées… Voici ma session préférée:Windows Azure Internals

Mark Russinovich (qu’on ne présente plus) montre l’autre côté du miroir pour Azure.

Eléments les plus marquants:

  • ~10 personnes pour administrer 100 000 serveurs physiques!
  • Démonstration d’une interface d’administration Azure,
  • Vue graphique des racks avec les VM,
  • Démonstration de self healing de la plateforme,
  • Explications sur le bug du 29 février, avec la ligne de commande qui a tout planté

Je vous préviens, c’est du lourd 🙂

Elle est disponible en ligne ici (slides + vidéo): http://channel9.msdn.com/events/TechEd/Europe/2012/AZR302

GPMC : 0x80070005 – access denied – E_Accessdenied

En voulant modifier une GPO chez un client, j’ai eu ce message d’erreur GPMC, et la GPO n’est effectivement pas modifiée:

En utilisant Process Monitor, de Sysinternals, l’accès au fichier registry.pol est refusé alors que mon compte est admin du domaine:


Suite à un incident et une restauration autoritaire, les fichiers ont en fait l’attribut lecture seule:

Après avoir décocher l’attribut lecture seule, la modification des GPO fonctionnent de nouveau 🙂

Restaurer une base SQL server via powershell

clear

#---------------------------------------------------
$server="mysqlserver"
$endpoint_port="5022"
$instance="myNamedSQLinstance"
$emailFrom = "provisioning@mydomain.com"
$emailTo = "mathieu.chateau@lotp.fr"
$smtpServer = "mysmtpserver"
$sendmail=$true
$foldersource='\myfileserverbackupFromDev$'
$folderarchived='\myfileserverbackupFromDev$done'
$excludeList=@()
$excludeList+='master'
$excludeList+='tempdb'
$excludeList+='model'
#---------------------------------------------------
$foldersource="c:"
$folderarchived="F:"

$majorError=$true
$global:log=@()
try
{
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO")  | out-null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum")
    $source = new-object ('Microsoft.SqlServer.Management.Smo.Server') "$server$instance"
    $majorError=$false
}
catch
{
       AddLog "major error, one side not reachable $_"
       "major error, one side not reachable $_"
       $majorError=$true
}

function AddLog($text)
{
       $global:log+=$text
       Write-Host $text
}

if ($majorError -eq $false)
{
       $databases = $source.Databases
       foreach ($file in (Get-childitem $foldersource -Filter "*.bak"))
       {
               $dbname=$file.Name -replace (".bak","")
               if ($excludeList -notcontains $dbname)
            {
                #not on the blacklist
                if (($databases | ?{$_.Name -ieq $dbname}) -eq $null)
                {
                    #database does not exist
                    try
                    {
                        #Restore
                        $targetDBFilePath = $source.MasterDBPath + "" + $dbName + ".mdf"
                        $targetLogFilePath = $source.MasterDBLogPath + "" + $dbName + ".ldf"
                        AddLog "   going to restore $dbname to:"
                        AddLog "   $targetDBFilePath and $targetLogFilePath"
                        $restore = new-object ('Microsoft.SqlServer.Management.Smo.Restore')
                        $restore.Action = 'Database'
                        $restore.Database = $dbname
                        ##$backupDataFile=$dbbk.Devices[0].Name
                        #$restore.Devices.AddDevice($backupDataFile, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
                        $backupfile=New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem")($file.FullName, "File")
                        $restore.Devices.Add($backupfile)
                        #$restoredetails=$restore.ReadBackupHeader($source)
                        $relocateDataFile = new-object ('Microsoft.SqlServer.Management.Smo.RelocateFile')
                        $relocateLogFile  = new-object ('Microsoft.SqlServer.Management.Smo.RelocateFile')
                        $dbFileList = $restore.ReadFileList($source)
                        $relocateDataFile.LogicalFileName = $dbFileList.Select("Type = 'D'")[0].LogicalName
                        $relocateDataFile.PhysicalFileName = $targetDBFilePath
                        $relocateLogFile.LogicalFileName = $dbFileList.Select("Type = 'L'")[0].LogicalName
                        $relocateLogFile.PhysicalFileName = $targetLogFilePath
                        $restore.RelocateFiles.Add($relocateDataFile)
                        $restore.RelocateFiles.Add($relocateLogFile)
                        $restore.ReplaceDatabase = $False
                        $restore.NoRecovery = $False
                        $restore.SqlRestore($source)
                        AddLog "     Restore done"
                        Move-Item $file.FullName $folderarchived
                    }
                    catch
                    {
                        AddLog "    error during restore: $_"
                        $majorError=$true
                        break
                    }
                    
                }
                else
                {
                    #blacklisted name
                    AddLog "database $dbname / $($files.Names) already exist"
                }
            }
            else
            {
                AddLog "Forbidden databasename: $dbname"
            }
       
       }
}

if($sendmail)
{
       $temp=""
       foreach ($line in $log)
       {
              $temp+=$line+"`r`n"
       }
       $smtp = new-object Net.Mail.SmtpClient($smtpServer)
       $smtp.Send($emailFrom, $emailTo,"SQL mirror automator",$temp)
}


$log

Ferme RDP avec broker: comment accéder à un serveur spécifique ?

Hypothèses

  • Vous avez une ferme RDP avec par exemple 2 serveurs RDP,
  • Vous avez le broker en place, donc les utilisateurs sont redirigés vers leur connexion actuelle (affinité),
  • You avez restreint à une session par utilisateur.

Problème

Quand vous essayez de joindre un serveur RDP spécifique de la ferme (pour faire de l’admin dessus ou aider un utilisateur qui est dessus), vous êtes refusé:

La connexion ne peut pas être établie car l’ordinateur distant qui a été joint n’est pas celui que vous avez spécifié. 
Cela peut être dû à une entrée obsolète du cache DNS. Essayez d’utiliser l’adresse IP de l’ordinateur à la place du nom.

 

Idem en essayant par l’adresse IP comme suggéré:

Cet ordinateur ne peut pas se connecter à l’ordinateur distant.

L’ordinateur distant auquel vous essayez de vous connecter vous redirige vers l’ordinateur distant. 
La Connexion Bureau à distance ne peut pas vérifier que les deux ordinateurs distants appartiennent à la même batterie de serveurs. 
Ceci peut se produire si un autre ordinateur du réseau porte le même nom que celui auquel vous tentez de vous connecter.

 

Solution

Il suffit d’utiliser le fameux /admin du client RDP pour bypasser les règles !

 

 

SharePoint 2010: CAPI2 failed extract root list the data is invalid

Un des serveurs SharePoint 2010 a soudainement généré le message d’erreur suivant « en masse » (toutes les 20 secondes):

Failed extract of third-party root list from auto update cab at....With error: the data is invalid

CAPI2 Failed extract thirdt party data is invalid

L’impact le plus notable est une très grosse lenteur soudaine et persistante, alors que SQL et le cpu ne pas solicité.

Il est connu que les assembly .Net sont signés, et que par défaut Windows cherche à valider leur signature. Cela peut poser des lenteurs supplémentaires au 1er appel des application pools. J’avais d’ailleurs déjà écrit un billet à ce sujet pour SharePoint 2007.

Mais là c’est bien après le 1er appel, et le serveur a accès à Internet directement.

Une trace wireshark montre tout de suite des essais répétés pour télécharger des certificats:

Pour tracer le coupable, il suffit d’aller dans la vue détaillée de l’eventlog, et de récupérer le PID du processus qui a généré l’erreur (344):

Lancez ensuite Process Monitor de Sysinternals, en filtrant sur le PID 344:

On voit des essais répétés sur un fichier temporaire de type Cab.tmp, qu’il essaye de copier dans cryptneturlCache.

Je suis tombé sur cet article d’un autre MVP, et j’ai appliqué la KB indiquée même si l’erreur de correspondait pas exactement.

  • L’erreur dans l’eventlog disparait immédiatement,
  • Mais les lenteurs persistent.

J’ai constaté qu’il essayait toujours de télécharger le fichier (en prenant un 304 not modified à chaque fois).

J’ai fais une variante de l’article ci-dessus, j’ai supprimé le dossier CryptNetUrlCache mais dans le profile du compte AD SharePoint.

Et voilà ^^

SharePoint 2010: Unable to index into an object of type Microsoft.SharePoint.SPListItem

En voulant peupler une liste SharePoint via PowerShell, j’ai le message d’erreur suivant:

Unable to index into an object of type Microsoft.SharePoint.SPListItem.
 + $newItem[ <<<< "column_name"] = $SPFieldUserValue
 + CategoryInfo : InvalidOperation: (column_name:String) [], RuntimeException
 + FullyQualifiedErrorId : CannotIndex

Le nom des colonne est sensible à la casse, j’avais oublié une majuscule!

SharePoint 2010 – Accès refusé en boucle

Symptômes

  • Lorsque vous essayez d’accéder aux sites SharePoint, vous bouclez sur un accès refusé quelque soit le compte
  • Dans les logs : 
    SPWindowsTokenCacheServiceApplication.CacheHandle() call to OpenProcess() failed for '0#.w|mondomainemonlogin': PID=2956, ErrorCode=5, Exception=System.ComponentModel.Win32Exception: Access is denied
    The Secure Store Service application Secure Store Service is not accessible. The full exception text is: Cannot open database "Secure_Store_Service_DB_guid" requested by the login. The login failed.  Login failed for user 'mondomaineaccount'

Résolution

Security Token Service Application doit tourner avec le compte admin de la ferme