You need to nest powershell.exe calls:
An outer call that calls PowerShell's Start-Process cmdlet with -Verb RunAs, which allows running any executable with elevation.
 
Since what you want to run with elevation is a .ps1 script, it must be called via powershell.exe, the Windows PowerShell CLI, as in your own attempt, except that you explicitly need to incorporate a Set-Location call to ensure that the script runs in the same working dir. as the caller (C:\Windows\System32 is the default in Windows PowerShell when Start-Process -Verb RunAs is used).
- If you don't need this, or if you're using 
pwsh.exe, the CLI of the cross-platform PowerShell (Core) 7+ edition (which now retains the working dir. by default), the inner call can be simplified to (replace powershell.exe with pwsh.exe in both places to use PowerShell 7+): 
powershell.exe -Args '-noprofile -file D:\Cyber_security\Python\login.ps1' 
 
# See bottom section if you also want to get the exit code of 
# the elevated process.
p = subprocess.Popen(
  [
    "powershell.exe", 
    "-noprofile", "-c",
    r"""
    Start-Process -Verb RunAs -Wait powershell.exe -Args "
      -noprofile -c Set-Location \`"$PWD\`"; & D:\Cyber_security\Python\login.ps1
      "
    """
  ],
  stdout=sys.stdout
)
p.communicate()
Note:
Running a process with elevation:
- involves an interactive UAC confirmation / credentials prompt that cannot be bypassed (unless UAC is turned off, which would be ill-advised)
 
- invariably runs in a new window.
 
- prevents direct capture of the elevated process' output streams; you'll have to redirect to (temporary) files instead, which you can do with 
Start-Process' 
-RedirectStandardOutput / -RedirectStandardError parameters. 
 
CLI parameters -noprofile and -c were added: -noprofile suppresses loading of PowerShell's profiles, and -c (-Command) explicitly indicates that what follows are PowerShell commands to execute.
 
-Wait was added to the Start-Process call above so as to make the outer powershell.exe call wait for the elevated process to exit before continuing.
 
You don't strictly need powershell.exe + Start-Process -Verb RunAs for launching an elevated process, but it is the most convenient option.
- A Python-based solution is possible, but involves fairly complex use of the WinAPI - see this blog post
 
- Note that while you can technically use 
runas.exe /user:Administrator utility to create an elevated session, doing so (a) only works with precisely that account, i.e. the built-in account named Adminstrator, and that account is often disabled in practice (it is disabled by default). 
 
An alternative approach would be to modify the .ps1 file to self-elevate on demand (or use a helper .ps1 file that does that) - see this answer
 
Variation that also gets the exit code of the elevated process:
If your .ps1 script uses the exit statement in order to deliberately report a (process) exit code that signals success vs. failure and you want to query that exit code, a bit more work is needed:
Start-Process -PassThru switch outputs a process-information object representing the newly launched process, whose .ExitCode property reports the process exit code (after termination).
 
Due to how the -c / -Command CLI parameter works, the inner powershell.exe call must use exit $LASTEXITCODE explicitly to relay the script's exit code as the elevated process' exit code.
 
p = subprocess.Popen(
  [
    "powershell.exe", 
    "-noprofile", "-c",
    r"""
    exit (
      Start-Process -Verb RunAs -PassThru -Wait powershell.exe -Args "
        -noprofile -c Set-Location \`"$PWD\`"; & C:\Users\jdoe\Desktop\pg\pg.ps1; exit `$LASTEXITCODE
      "
    ).ExitCode
    """
  ],
  stdout=sys.stdout
)
p.communicate()
print('Terminated with exit code ' + str(p.returncode))