J'ai un système d'exploitation d'agent SQL Server 2014 (type: "Système d'exploitation (CMDEXEC)", exécuté comme: "Compte de service SQL Server Server", propriétaire: SA) qui exécute la commande suivante:
powershell -ExecutionPolicy Bypass -Command "$objServiceManager = New-Object -ComObject 'Microsoft.Update.ServiceManager'; $objService = $objServiceManager.AddService2('7971f918-a847-4430-9279-4a52d1efe18d',2,''); $objService.PSTypeNames.Add('PSWindowsUpdate.WUServiceManager');"
Le compte de service que SQL Server Agent est exécuté sous Sysadmin Privilèges à l'instance, mais n'a pas d'accès administrateur au serveur.
Si je suis dans le serveur en tant que compte de service de l'agent, je peux exécuter la commande avec succès à partir d'une invite de commande:
Mais si j'exécute le travail de l'agent SQL Server, il échoue avec une erreur "Accès refusé":
Exception calling "AddService2" with "3" argument(s): "Access is denied.
(Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
At line:1 char:79
+ $objServiceManager = New-Object -ComObject
'Microsoft.Update.ServiceManager'; $o ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
You cannot call a method on a null-valued expression.
At line:1 char:170
+ ... efe18d',2,'');
$objService.PSTypeNames.Add('PSWindowsUpdate.WUServiceManager');
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
J'ai constaté que si je définissais le "Courant" comme "pour le poste à un compte proxy contenant des privilèges Sysadmin sur l'instance et l'accès administrateur au serveur, il réussit, mais ce n'est pas vraiment pertinent pour ma question.
EDIT: J'exécute tout comme CMDEXEC, et non PowerShell, car je dois exécuter un script de PowerShell non signé (non inclus dans mon code, car cela ne cause pas de problème). Je reçois la même erreur si je change le type à PowerShell.
Ma question: Pourquoi la même commande échoue-t-elle qu'un travail, mais réussisse de la console lorsqu'elle est exécutée à partir du même compte d'utilisateur sur le même serveur?
Puisque vous exécutez PowerShell via SQL Server CmdExec
à partir d'un travail d'agent, vous pouvez essayer d'appeler un script PowerShell avec votre logique PS enregistrée dans celle-ci plutôt que d'exécuter des commandes RAW PowerShell pour voir si cela fait une différence pour un potentiel. solution de contournement.
Essayez de placer explicitement le chemin d'exploitation complet sur le serveur pour pointer vers PowerShell.exe
Et ensuite transmettre vos commandes PowerShell après cela, si la question a trait à des variables environnementales ne fonctionnant pas correctement pour PowerShell dans la coquille CmdExec
.
Ma question: Pourquoi la même commande échoue-t-elle qu'un travail, mais réussisse de la console lorsqu'elle est exécutée à partir du même compte d'utilisateur sur le même serveur?
PowerShell.exe
à travers le travail d'agent SQL Server avec le shell CmdExec
_ Shell et comment il interprète le contexte de sécurité du compte, il est exécuté à partir de ou comme (par exemple, le compte de service) lorsqu'il essaie d'exécuter PowerShell.exe
De cette façon, il n'est donc pas capable d'authentifier l'accès à l'exécution à l'exe en raison de cela.Tu devras:
<DomainName>\<ServiceAccount>
)<DomainName>\<ServiceAccount>
)<DomainName>\<ServiceAccount>
) des informations d'identification du compte,Vous trouverez ci-dessous un script de la partie T-SQL de ce processus que je cours après avoir effectué 4 étapes ci-dessus, et cela fonctionne toujours dans mon environnement pour accomplir ce qui semble être similaire à ce que vous avez expliqué que vous essayez d'accomplir . Je dois également vous assurer que le compte d'annonces ait un mot de passe fort/complexe et de le définir pour ne jamais expirer.
--- // Create login on SQL Instance for domain\PSSQLJobs service account if it does not exist
IF NOT EXISTS (
SELECT *
FROM sys.server_principals
WHERE NAME = N'domain\PSSQLJobs'
)
BEGIN
CREATE LOGIN [domain\PSSQLJobs]
FROM WINDOWS WITH DEFAULT_DATABASE = [master]
,DEFAULT_LANGUAGE = [us_english]
END
USE [master]
IF NOT EXISTS (
SELECT *
FROM sys.database_principals
WHERE NAME = N'domain\PSSQLJobs'
)
CREATE USER [domain\PSSQLJobs]
FOR LOGIN [domain\PSSQLJobs]
WITH DEFAULT_SCHEMA = [dbo]
EXEC sp_addrolemember N'db_datareader'
,N'domain\PSSQLJobs'
GRANT CONNECT
ON DATABASE::[master]
TO [domain\PSSQLJobs]
USE [msdb]
IF NOT EXISTS (
SELECT *
FROM sys.database_principals
WHERE NAME = N'domain\PSSQLJobs'
)
CREATE USER [domain\PSSQLJobs]
FOR LOGIN [domain\PSSQLJobs]
WITH DEFAULT_SCHEMA = [dbo]
EXEC sp_addrolemember N'db_datareader'
,N'domain\PSSQLJobs'
EXEC sp_addrolemember N'SQLAgentOperatorRole'
,N'domain\PSSQLJobs'
EXEC sp_addrolemember N'SQLAgentReaderRole'
,N'domain\PSSQLJobs'
EXEC sp_addrolemember N'SQLAgentUserRole'
,N'domain\PSSQLJobs'
GRANT CONNECT
ON DATABASE::[msdb]
TO [domain\PSSQLJobs]
--- // Create Credential *** Type in password of account into value of SECRET ***
USE [msdb]
CREATE CREDENTIAL PSSQLJobs
WITH IDENTITY = 'domain\PSSQLJobs'
,SECRET = '*******'
--- // Create PowerShell Proxy account and give PSSQLJobs access to it
USE [msdb]
EXEC msdb.dbo.sp_add_proxy @proxy_name = N'ExecutePowershell'
,@credential_name = N'PSSQLJobs'
,@enabled = 1
EXEC msdb.dbo.sp_grant_proxy_to_subsystem @proxy_name = N'ExecutePowershell'
,@subsystem_id = 12
EXEC msdb.dbo.sp_grant_login_to_proxy @proxy_name = N'ExecutePowershell'
,@login_name = N'domain\PSSQLJobs'